You are on page 1of 9

2.

Το βήμα των χρηστών


Στη συνέχεια θα αναπτύξουμε μια εφαρμογή στην οποία οι επισκέπτες θα μπορούν να αναρτούν τις
απόψεις τους για διάφορα θέματα. Πρόκειται, υπό μια έννοια, για ένα βήμα όπου κάποιος θα είναι
σε θέση να εκφράζει την άποψή του και να «ανοίγει» μια συζήτηση.

Η εφαρμογή «το βήμα των χρηστών» (pitch από εδώ και πέρα) αποτελείται από χρήστες (users)
και τα μηνύματά τους (posts). Θα προσπαθήσουμε να αναπτύξουμε την εφαρμογή στο δυνατό
λιγότερο χρόνο.

2.1 Σχεδιασμός της εφαρμογής

Η εφαρμογή προφανώς αποτελείται από δύο οντότητες: users και posts.

Μοντελοποίηση users

Το μοντέλο user για κάθε χρήστη περιλαμβάνει:

• μοναδικό id
• όνομα
• επώνυμο
• διεύθυνση email και
• συνθηματικό

(Στην πραγματικότητα επίσης θα περιλαμβάνει ένα registration_key, καθώς επίσης και ένα
reset_password_key, αλλά δεν χρειάζεται να τα ξέρουμε και όλα, έτσι;)

Μοντελοποίηση posts

Το μοντέλο post, ακόμη πιο απλό, περιλαμβάνει:

• μοναδικό id
• το περιεχόμενο (content) του μηνύματος και
• το user_id του χρήστη που ανάρτησε το μήνυμα

Σχέση μεταξύ users και posts

Όπως έχετε ήδη αναγνωρίσει, οι δύο πίνακες (μοντέλα για το web2py) παρουσιάζουν μια
συγκεκριμένη σχέση. Ένας χρήστης μπορεί να γράψει από κανένα έως έναν απεριόριστο αριθμό
μηνυμάτων, ενώ κάθε μήνυμα γράφεται από (ανήκει σε) έναν και μόνο έναν χρήστη.
2.2 Ανάπτυξη

Στο προηγούμενο μάθημα δημιουργήσαμε μια καινούρια εφαρμογή από το γραφικό περιβάλλον
web του framework.Ας δούμε τώρα ένα διαφορετικό τρόπο να δημιουργήσουμε μια εφαρμογή
εκκίνησης. Στη γραμμή εντολών του τερματικού σας μπείτε στον κατάλογο του web2py και δώστε
τις εξής εντολές:

1. C:
2. cd\
3. cd web2py.dat
4. python web2py.py –S pitch

Εφόσον εφαρμογή με τέτοιο όνομα δεν υπάρχει, το framework θα αποκριθεί πληροφορώντας μας
γι’ αυτό και θα ρωτήσει εάν θέλουμε να δημιουργηθεί μια εφαρμογή εκκίνησης με αυτό το όνομα.
Απαντήστε ‘yes’ (ή ‘y’) στην ερώτηση. Η εφαρμογή pitch θα δημιουργηθεί και το web2py θα μας
εισάγει σε ένα κέλυφος python (python shell από εδώ και πέρα) αναμένοντας εντολές. Προς το
παρόν πατήστε Ctrl + D και “yes” για να βγείτε από το python shell.

Όλα τα μοντέλα στην πασαρέλα!

Είναι ώρα να δημιουργήσουμε τα μοντέλα μας σύμφωνα με το σχέδιο που κάναμε κατά τη
σχεδίαση της εφαρμογής. Πρέπει δηλαδή να δημιουργήσουμε το μοντέλο user και το μοντέλο post.
Τα καλά νέα είναι ότι το web2py καθόρισε κατευθείαν το μοντέλο user κατά τη διάρκεια
δημιουργίας της εφαρμογής εκκίνησης. Πρόκειται για τον πίνακα auth_user που ανήκει στο
μοντέλο db, αναφέρεται δε ως db.auth_user.1 Προς το παρόν, το μοντέλο αυτό είναι αρκετό. Για πιο
σύνθετες εφαρμογές το web2py προσφέρει εργαλεία για να τροποποιήσουμε τα μοντέλα μας και να
τα προσαρμόσουμε στις ανάγκες μας.

Με το notepad++ ανοίξτε το αρχείο db.py που βρίσκεται στο folder models και στο τέλος του
προσθέστε τον εξής κώδικα:

94. db.define_table('post',
95. Field('minima', 'text'),
96. Field('user_id', db.auth_user)
97. )

Αυτό που μόλις κάναμε είναι να ορίσουμε ένα πίνακα με δύο πεδία: ένα πεδίο τύπου σημειώσεων
(text) και ένα πεδίο αναφοράς (‘foreign key’ για τους πιο ψαγμένους στις βάσεις δεδομένων) το
οποίο παραπέμπει (συνδέει) κάθε μήνυμα με κάποια εγγραφή στον πίνακα των χρηστών (user). Το
πεδίο id για τον πίνακα post δεν χρειάζεται να το ορίσουμε, καθώς δημιουργείται αυτόματα από το
web2py - όπως άλλωστε συμβαίνει και για όλους τους πίνακες που δημιουργούνται από το
framework στη βάση δεδομένων.

Ας δούμε τι φτιάξαμε μέχρι τώρα: Πλοηγηθείτε στο http://127.0.0.1:8000/pitch/default/user/register


και εγγράψτε ένα χρήστη. Στη συνέχεια κάνετε login στη διεύθυνση
http://127.0.0.1:8000/pitch/default/user/login. Επίσης μπορείτε να δείτε το προφίλ του χρήστη στο
http://127.0.0.1:8000/pitch/default/user/profile.

1
Για τη αναπαράσταση της βάσης δεδομένων στην εφαρμογή μας (μοντελοποίηση, db) θα μιλήσουμε αργότερα.
Post – άρετε ελεύθερα!

Για να μπορέσει ο χρήστης μας να αναρτήσει ένα μήνυμα στο site, χρειάζεται να δημιουργήσουμε
ένα κατάλληλο ενδιάμεσο διεπαφής (interface). Αυτό δεν θα είναι τίποτε άλλο παρά μια ιστοσελίδα
με μια φόρμα, την οποία θα μπορεί ο χρήστης να συμπληρώνει και να υποβάλλει.

Γρήγορα, στο notepad++ και ανοίγουμε το αρχείο default.py που βρίσκεται στο folder
controllers2. Δημιουργήστε μια συνάρτηση ονομάζοντάς την ‘enter_post()’ στο τέλος του αρχείου:

1. def enter_post():
2. “““Επιστρέφει μια φόρμα για εισαγωγή μηνυμάτων”””
3. formForMessage = crud.create(db.post)
4. return dict(form=formForMessage)

και αποθηκεύστε το. Τώρα πλοηγηθείτε στο http://127.0.0.1:8000/pitch/default/enter_post και θα


δείτε ότι το web2py δημιούργησε αυτόματα μια φόρμα για την εισαγωγή μηνυμάτων από το
χρήστη.

Με τη δημιουργία της φόρμας εισαγωγής, ουσιαστικά γράψαμε σε γλώσσα Python την πρώτη μας
υπο-ρουτίνα3, η οποία έρχεται πάντα υπό το κέλυφος μιας συνάρτησης. Θα επανέλθουμε στις
συναρτήσεις αργότερα. Προς το παρόν κρατήστε ότι η πρώτη γραμμή κατά τον ορισμό τους αρχίζει
με def και τελειώνει με ‘:’ ενώ το υπόλοιπο σώμα της συνάρτησης πρέπει να ακολουθεί τη
σύμβαση εσοχών της Python.

Στη δεύτερη γραμμή της συνάρτησης enter_post() δημιουργούμε τη φόρμα εισαγωγής μηνυμάτων
καλώντας ένα στιγμιότυπο (instance) του αντικειμένου CRUD4 του web2py. Πρόκειται για ένα
τυποποιημένο τρόπο χειρισμού εγγραφών στις βάσεις δεδομένων. Το web2py υποστηρίζει κι
άλλους πιο κομψούς ή πολύπλοκους μηχανισμούς, αλλά προς το παρόν θα αρκεστούμε στον
CRUD. Η τελευταία γραμμή της συνάρτησης επιστρέφει τη φόρμα που φτιάξαμε ως αντικείμενο
στην αντίστοιχη view.
2
Όπως ίσως παρατηρείτε, από εδώ και πέρα θα ανοίγουμε τα διάφορα αρχεία με εξειδικευμένους επεξεργαστές κειμένων
(όπως το notepad++) και όχι με το υποσύστημα επεξεργασίας του web2py.
3
Υπο-Ρουτίνα (Wikipedia): Στην επιστήμη των υπολογιστών, μια υπο-ρουτίνα (που επίσης καλείται διαδικασία,
συνάρτηση, ρουτίνα, μέθοδος ή υποπρόγραμμα) είναι τμήμα κώδικα μέσα σε ένα μεγαλύτερο πρόγραμμα το οποίο
διεκπεραιώνει κάποια συγκεκριμένη αποστολή και είναι σχετικά ανεξάρτητο από τον υπόλοιπο κώδικα.
4
CRUD (Wikipedia): Στον προγραμματισμό, οι τέσσερις βασικές ρουτίνες αλληλεπίδρασης με ένα σύστημα μόνιμης
αποθήκευσης δεδομένων (database) είναι οι Create, Read, Update and Delete (CRUD). Σε κάποιες περιπτώσεις η
CRUD επεκτείνεται ανταλλάσσοντας τους όρους ‘read’ και ‘delete’με τους ‘retrieve’ και ‘destroy’ αντίστοιχα. Ο όρος
CRUD συχνά επίσης χρησιμοποιείται για να περιγράψει αντικείμενα διεπαφής τα οποία διευκολύνουν τη θέαση, την
αναζήτηση τη διαγραφή και την επικαιροποίηση πληροφοριών μέσω φορμών και αναφορών σε υπολογιστές.
Παρατηρούμε ότι το framework έχει χρησιμοποιήσει ως ετικέτες τα ονόματα των πεδίων, όπως
αυτά ορίσθηκαν κατά τη δημιουργία των μοντέλων auth_user και post. Μονολιθικό; Για να
δούμε…

Ακόμη στο notepad++, ανοίξτε πάλι το αρχείο db.py (θυμάστε πού βρίσκεται;), τροποποιήστε το
μοντέλο του πίνακα post ως εξής:

1. db.define_table('post',
2. Field('minima', 'text', label = ‘Μήνυμα’),
3. Field('user_id', db.auth_user)
)

και αποθηκεύστε το αρχείο. Επιστρέψτε στο http://127.0.0.1:8000/pitch/default/enter_post και


ανανεώστε τη σελίδα. Παρατηρείτε καμιά αλλαγή; Είναι τώρα ώρα να εισάγετε μερικά μηνύματα
για το χρήστη σας.

One ring to rule them all…

… αρκεί να έχει πρόσβαση! Θα εισάγουμε στη φόρμα τον περιορισμό να επιτρέπεται η εισαγωγή
μηνυμάτων μόνο σε εξουσιοδοτημένους χρήστες. Απλό:

notepad++, αρχείο default.py και τροποποιούμε τη συνάρτηση της φόρμας ως εξής:

1. @auth.requires_login()
2. def enter_post():
3. “““Επιστρέφει μια φόρμα για εισαγωγή μηνυμάτων”””
4. formForMessage = crud.create(db.post)
5. return dict(form=formForMessage)

Ουσιαστικά προσθέσαμε τον κώδικα @auth.requires_login() μια γραμμή ακριβώς επάνω από τη
συνάρτηση (χωρίς να μεσολαβεί κενή γραμμή). Η λειτουργία της είναι να απαιτεί Login από όποιον
χρήστη επιχειρεί να ανοίξει το αντίστοιχο view. Η εντολή αυτή, παρότι έξω από τη συνάρτηση,
αποτελεί αναπόσπαστο κομμάτι αυτής. Δεν έχει ενέργεια σε καμιά άλλη. Τέτοιες γραμμές
καλούνται «διακοσμητές» (decorators), αρχίζουν πάντα με ‘@’ και βρίσκονται ακριβώς επάνω από
τον ορισμό της συνάρτησης. Ένας πολύ χρήσιμος τέτοιος διακοσμητής που θα χρησιμοποιείτε
συχνά είναι ο @auth.requires_membership(‘something’). Όπως δείχνει το όνομά του, ο χρήστης
δεν αρκεί μόνο να κάνει login, αλλά απαιτείται επίσης να ανήκει και σε συγκεκριμένο/α group/s για
να έχει πρόσβαση στις διάφορες περιοχές του μοντέλου μας. Σε περίπτωση που μη
εξουσιοδοτημένος χρήστης επιχειρήσει να προσπελάσει μια προστατευμένη σελίδα, το web2py θα
τον ενημερώσει με ένα μήνυμα flash.

Εάν ανανεώσετε τη σελίδα, θα εμφανισθεί μια φόρμα Login στην οποία θα πρέπει να δώσετε τα
email/password που δηλώσατε κατά την εγγραφή σας, πριν το σύστημα δεχθεί οποιαδήποτε
καταχώρηση μηνύματος εκ μέρους σας.

Στην πρώτη σελίδα

Σαν ένα τελευταίο βήμα, θα τροποποιήσουμε την εφαρμογή μας ώστε να δείχνει τους χρήστες και
τα μηνύματά τους στην πρώτη σελίδα της.

Μετατρέψτε τη συνάρτηση index() στον controller default ως εξής:

1. def index():
2. """Δείχνει τους χρήστες και τα μηνύματά τους"""
3. users = db(db.auth_user.id > 0).select()
4. posts = db(db.post.id > 0).select()
5. return dict(users=users, posts=posts)

Στην πρώτη σελίδα του site θα φαίνονται όλοι οι χρήστες και τα μηνύματά τους:

Στην περίπτωση αυτή, χρησιμοποιήσαμε τη δυνατότητα του web2py να δημιουργεί σύνολα


εγγραφών από τη βάση δεδομένων, να φιλτράρει με δεδομένη ερώτηση το σύνολο αυτό και να
επιστρέφει το αποτέλεσμα ως αντικείμενο στην αντίστοιχη view. Οι γραμμές 3 και 4 στον
παραπάνω κώδικα δημιουργούν δύο τέτοια αντικείμενα εγγραφών (users και posts) τα οποία στη
διάλεκτο του web2py ονομάζονται (Rows). Κάθε αντικείμενο Rows έχει τη μορφή:

db(συνθήκη αναζήτησης).select(λίστα πεδίων)

Τα αντικείμενα εγγραφών αποθηκεύονται σε μεταβλητές (σειρές 3 και 4) οι οποίες στη συνέχεια


επιστρέφονται στην αντίστοιχη view (σειρά 5). Περισσότερα γι’ αυτά αργότερα…

Το menu παρακαλώ…

Στο σημείο αυτό θα προσθέσουμε ένα κεντρικό menu πλοήγησης στην εφαρμογή μας.

Ανοίξτε το αρχείο menu.py που βρίσκεται στο folder models βρείτε το τμήμα που αναφέρεται στο
Menu και αλλάξτε τον ως εξής:

1. response.menu = [
['Αρχική',False,URL('default','index')],
['Εισαγωγή Μηνυμάτων',False,URL('default','enter_post'),[]]
]

Το αντικείμενο response.menu είναι υπεύθυνο για την εμφάνιση του κεντρικού menu πλοήγησης
στις σελίδες της εφαρμογής μας. Πρόκειται για μια δομή λίστας, κάθε αντικείμενο της οποίας
αποτελείται από υπο-λίστες, κάθε μία από τις οποίες αντιπροσωπεύει μια επιλογή του κεντρικού
menu. Σε κάθε υπο-λίστα:

• το πρώτο μέλος είναι το όνομα που θα εμφανίζεται στο menu


• τo δεύτερο ούτε να το συζητάτε μέχρι … νεωτέρας, απλά το ορίζετε ως False και είστε ok
• τo τρίτο μέλος είναι η σελίδα που θα επισκεφθεί ο χρήστης όταν πατήσει την επιλογή αυτή του
menu. Αποτελείται από το όνομα του controller και το όνομα της συνάρτησης (η οποία όπως
έχουμε ήδη δει έχει πάντα μια προεπιλεγμένη view) και τέλος,

• σε κάθε υπο-λίστα υπάρχει προαιρετικά και ένα τελευταίο μέλος, μια υπο-υπο-λίστα. Αυτή
χρησιμοποιείται για να αποκτήσει νέα μέλη η επιλογή αυτή του κεντρικού menu (δενδροειδής
μορφή του menu), με τον ίδιο ακριβώς τρόπο.

Το εισιτήριο προς το … λάθος (Ticketing system)

Αποδεχθείτε το τώρα, για να μην απογοητευθείτε: τις περισσότερες φορές, στην αρχή τουλάχιστον,
θα κάνετε πολλά τυπογραφικά λάθη (μπορεί και λάθη ροής ή λογικά). Κατά συνέπεια θα έρχεστε
συχνά αντιμέτωποι με το σύστημα διόρθωσης λαθών του web2py που, πιστέψτε με, είναι ο
καλύτερός σας φίλος. Προσπαθεί να αναλύσει τον κώδικά σας και να σας κατευθύνει όσο το
δυνατό σωστότερα προς την κατάλληλη λύση.

Ας προσομοιώσουμε ένα τέτοιο λάθος για να δούμε πώς δουλεύει η ιστορία αυτή: μετατρέψτε τη
συνάρτηση enter_post() στον controller default.py ως εξής:

1. @auth.requires_login()
2. def enter_post():
3. “““Επιστρέφει μια φόρμα για εισαγωγή μηνυμάτων”””
4. formForMessage = crid.create(db.post)
5. return dict(form=formForMessage)

…κάναμε λάθος και αντί ‘crud’ πληκτρολογήσαμε ‘crid’ (σειρά 4). Όταν επισκεφθούμε τη σελίδα
http://127.0.0.1:8000/pitch/default/enter_post το web2py θα ζητήσει τα διαπιστευτήριά μας και στη
συνέχεια θα εκδώσει το εξής εισιτήριο λάθους:

Ο αριθμός αναφέρεται σε εσωτερική κωδικοποίηση του framework, ονομάζεται εισιτήριο λάθους


(error ticket) και δεν σας ενδιαφέρει αυτός καθαυτός. Αυτό που στην πραγματικότητα είναι
σημαντικό είναι η σελίδα που θα εμφανισθεί όταν κάνετε κλικ επάνω στο εισιτήριο αυτό:
Το web2py σας τσάκωσε! Βρήκε το λάθος και σας το αναφέρει: δεν υπάρχει καθορισμένο όνομα
μεταβλητής ή αντικειμένου ‘crid’! Διορθώστε το τώρα αμέσως!

2.3. Ροή πληροφορίας

Στο σημείο αυτό θα επεξηγηθεί η αρχή λειτουργίας του framework. Ίσως να αναρωτιέστε τι στην
ευχή κάνει το web2py με τους controllers, τις συναρτήσεις τους, τα views και τα μοντέλα.
Συνοπτικά, το framework χρησιμοποιεί ένα μηχανισμό διεκπεραίωσης (dispatching mechanism) για
να χειριστεί μια δεδομένη διεύθυνση (url). Κατά συνθήκη, μια διεύθυνση για το web2py έχει την
εξής μορφή:

http://hostname:port/application/controller/function/args?vars

Για παράδειγμα, για την εφαρμογή Pitch που μόλις γράψαμε, αυτό σημαίνει:

http://127.0.0.1:8000/pitch/default/enter_post

όπου

• 127.0.0.1:8000 = hostname:port
• pitch = application
• default = controller
• enter_post = function

Όταν το web2py δει μια τέτοια διεύθυνση κατευθείαν ψάχνει στον κατάλογο applications για
εφαρμογή που να ονομάζεται pitch. Εφόσον τη βρει, ανοίγει τον controller default και καλεί τη
συνάρτηση enter_post.
Στη συνέχεια η συνάρτηση enter_post αλληλεπιδρά με το μοντέλο και στέλνει τα
αποτελέσματα στο αντίστοιχο view μέσω του οποίου δημιουργείται η ιστοσελίδα που τελικά
αποστέλλεται στον περιηγητή του χρήστη.

Τα args και vars δεν τα έχουμε χρησιμοποιήσει ακόμη. Θα μπορούσαν να είναι για παράδειγμα
το id ενός χρήστη, ή κάτι που ο χρήστης έχει δηλώσει σε μια άλλη σελίδα της εφαρμογής μας.

Ορίστε κι ένα σχηματικό παράδειγμα της όλης διαδικασίας:

Άσκηση: Εισάγετε ένα καινούριο χρήστη και μερικά μηνύματα για το χρήστη αυτόν.

Άσκηση: Αλλάξτε τίτλο, υπότιτλο και υποσέλιδο των ιστοσελίδων της εφαρμογής σας με τα
εξής:

• Τίτλος:Το βήμα των εργαζομένων


• Υπότιτλος: Υπ.Α.Α.Τ.

• Υποσέλιδο: Το προ-καθορισμένο με την προσθήκη του Τμήματός σας.

Άσκηση: Προσθέστε δύο ακόμη σελίδες στην εφαρμογή σας. Στην πρώτη να φαίνονται μόνο
τα μηνύματα του ενός χρήστη και στη δεύτερη μόνο του άλλου.

Άσκηση: Προσθέστε μια καταχώριση με την ονομασία «Μηνύματα χρηστών» στο κεντρικό
menu. Η καταχώριση αυτή δεν πρέπει να δείχνει σε καμιά σελίδα, αλλά θα πρέπει να
περιλαμβάνει δύο επιλογές, μια για κάθε σελίδα που δημιουργήσατε στην
προηγούμενη άσκηση (με κατάλληλες ετικέτες).

Άσκηση: Καταργήστε την προηγούμενη εφαρμογή σας στο server shadow και αναρτήστε τη
νέα με την ίδια ονομασία (pitch_<το όνομα του χρήστη σας στο δίκτυο>).

You might also like