Οδηγός για προχωρημένους: Πως να γράψετε επαναχρησιμοποιήσιμα apps¶
Αυτός ο οδηγός για προχωρημένους ξεκινά μετά το τέλος του Οδηγού 7. Θα μετατρέψουμε την εφαρμογή ψηφοφορίας μας (Web-poll) σε ένα ξεχωριστό-ανεξάρτητο Python package το οποίο μπορείτε να επαναχρησιμοποιήσετε σε άλλα projects και να τα μοιραστείτε με άλλους προγραμματιστές.
Αν δεν έχετε ολοκληρώσει πρόσφατα τον Οδηγό του Django (μέρη 1 εως 7), σας ενθαρρύνουμε να ρίξετε μια ματιά (ή ακόμη και να τον ακολουθήσετε πλήρως) ούτως ώστε το project σας να συμβαδίζει με αυτό που θα ακολουθήσει.
Η επαναχρησιμοποίηση έχει σημασία¶
Απαιτεί πολύ δουλειά για να σχεδιάσετε, χτίσετε, τεστάρετε και διατηρήσετε μια web εφαρμογή (application). Πολλά Python και Django projects μοιράζονται κοινά προβλήματα. Δεν θα ήταν εξαιρετικά αν μπορούσαμε να γλυτώσουμε κάποιο μέρος από αυτή τη ρουτίνα;
Η επαναχρησιμότητα (reusability) είναι τρόπος ζωής στην Python. Το Python Package Index (PyPI) περιέχει μια πληθώρα από πακέτα (packages) τα οποία μπορείτε να χρησιμοποιήσετε στα δικά σας προγράμματα Python. Κοιτάξτε, επίσης, τα Django Packages για υπάρχουσες επαναχρησιμοποιημένες εφαρμογές (reusable apps) τις οποίες μπορείτε να ενσωματώσετε στο project σας. Το Django από μόνο του είναι άλλο ένα Python package. Αυτό σημαίνει ότι μπορείτε να πάρετε κάποια υπάρχον Python packages ή Django apps και να τα συνθέσετε για να δημιουργήσετε το δικό σας web project. Το μόνο που χρειάζεται είναι να γράψετε τα κομμάτια του κώδικα που θα κάνει το project σας μοναδικό.
Ας υποθέσουμε ότι ξεκινάτε ένα καινούργιο project το οποίο χρειάζεται μια εφαρμογή ψηφοφορίας όπως αυτή που ολοκληρώσατε στον Οδηγό του Django. Πώς κάνετε αυτή την εφαρμογή επαναχρησιμοποιήσιμη; Ευτυχώς, είστε όχι μόνο σε καλό δρόμο αλλά οδηγείτε κιόλας μέσα σε αυτόν! Στον Οδηγό 3, είδαμε πως μπορούμε να αποσυνδέσουμε σε επίπεδο URLconf, την εφαρμογή μας (polls) από το project μας, χρησιμοποιώντας τη συνάρτηση include
. Σε αυτό τον οδηγό, θα κάνουμε μερικά βήματα παραπέρα για να κάνουμε αυτή την εφαρμογή εύκολη προς την χρήση της σε άλλα project αλλά και έτοιμη να διανεμηθεί προς άλλους προγραμματιστές για να την χρησιμοποιήσουν (όπως χρησιμοποιείτε και εσείς, αν το κάνετε, άλλα apps από τη σελίδα Django Packages που αναφέραμε παραπάνω).
Package? App?
Ο όρος Python package παρέχει έναν τρόπο να ομαδοποιούμε Python κώδικα για εύκολη επαναχρησιμοποίηση. Ένα package περιέχει ένα ή περισσότερα αρχεία από Python κώδικα (επίσης γνωστά και ως “modules”).
Ένα package μπορεί να γίνει imported με τον κώδικα import foo.bar
ή from foo import bar
. Για να μετατραπεί ένας φάκελος (όπως ο φάκελος polls
) σε package, θα πρέπει να περιέχει ένα ειδικό αρχείο με το όνομα __init__.py
, ακόμη και αν αυτό το αρχείο είναι κενό.
Ένα Django application είναι απλώς ένα Python package το οποίο προορίζεται για χρήση, αποκλειστικά, από ένα Django project. Ένα application (εφαρμογή) μπορεί να χρησιμοποιεί κοινές Django πρακτικές, όπως το να υπάρχουν submodules σαν τα models
, tests
, urls
, και views
.
Αργότερα χρησιμοποιούμε τον όρο packaging για να περιγράψουμε την διαδικασία που χρειάζεται για να δημιουργηθεί ένα Python package. Μπορεί να σας μπερδεύει λιγάκι. Καταλαβαίνουμε!
Το project σας και η επαναχρησιμοποιήσιμη app¶
Κατόπιν ολοκλήρωσης των προηγούμενων οδηγών, η δομή του project μας θα πρέπει να έχει αυτή τη μορφή:
mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
wsgi.py
polls/
__init__.py
admin.py
migrations/
__init__.py
0001_initial.py
models.py
static/
polls/
images/
background.gif
style.css
templates/
polls/
detail.html
index.html
results.html
tests.py
urls.py
views.py
templates/
admin/
base_site.html
Δημιουργήσατε τον φάκελο mysite/templates
στον Οδηγό 7 και τον φάκελο polls/templates
στον Οδηγό 3. Τώρα ίσως φαίνεται πιο καθαρά ο λόγος που διαλέξαμε να έχουμε ξεχωριστούς template φακέλους για το project και για το application: οτιδήποτε είναι μέρος της εφαρμογής polls βρίσκεται μέσα στο polls
. Αυτό κάνει την εφαρμογή ανεξάρτητη και ευκολότερη να ενσωματωθεί μέσα σε ένα καινούργιο project.
Ο φάκελο polls
μπορεί εύκολα να αντιγραφεί σε ένα καινούργιο Django project και αμέσως να επαναχρησιμοποιηθεί. Δεν είναι, όμως, ακόμη έτοιμο να διανεμηθεί (εκδοθεί). Γι’ αυτό θα πρέπει να μετατρέψουμε την εφαρμογή μας σε ένα package για να διευκολύνουμε τους άλλους που θα την εγκαταστήσουν.
Εγκαθιστώντας μερικά προαπαιτούμενα¶
Η παρούσα κατάσταση του Python packaging είναι λιγάκι συγκεχυμένη με διάφορα εργαλεία. Για αυτό τον οδηγό, θα χρησιμοποιήσουμε το εργαλείο setuptools για να χτίσουμε το package (πακέτο) μας. Είναι το προτεινόμενο εργαλείο για packaging (το οποίο έχει γίνει merged με το fork του distribute
). Θα χρησιμοποιήσουμε, επίσης, το pip για να το εγκαταστήσουμε και να το απεγκαταστήσουμε. Θα χρειαστεί να εγκαταστήσετε τα δύο αυτά πακέτα τώρα. Αν χρειάζεστε βοήθεια, μπορείτε να ανατρέξετε στο πως να εγκαταστήσω το Django με το pip. Μπορείτε να εγκαταστήσετε το πακέτο setuptools
με τον ίδιο τρόπο.
Πακετάροντας το app σας¶
Το Python packaging αναφέρεται στην προετοιμασία του app σε μια συγκεκριμένη μορφή ούτως ώστε να μπορεί να εγκατασταθεί και να χρησιμοποιηθεί εύκολα. Το Django από μόνο του έχει πακεταριστεί με παρόμοιο τρόπο. Για μικρά apps όπως το polls, αυτή η διαδικασία δεν είναι δύσκολη.
Αρχικά, δημιουργήστε ένα φάκελο για την εφαρμογή
polls
, έξω από το Django project σας. Δώστε του όνομαdjango-polls
.Επιλέγοντας ένα όνομα για την εφαρμογή σας
Όταν διαλέγετε ένα όνομα για την εφαρμογή σας, ελέγξτε πρώτα μέσω του PyPI για τυχόν ήδη πιασμένα ονόματα άλλων εφαρμογών. Συχνά, είναι χρήσιμο να χρησιμοποιείται τη λέξη
django-
πριν το όνομα της εφαρμογής σας που πρόκειται να διανείμετε. Αυτό βοηθάει τους άλλους όταν κοιτάζουν συγκεκριμένα για Django apps προκειμένου να αναγνωρίσουν την εφαρμογή σας ως django-specific.Τα application labels (δηλαδή, η τελευταία λέξη των application packages στη διαδρομή με τις τελείες) πρέπει να είναι μοναδικό στη ρύθμιση
INSTALLED_APPS
. Αποφύγετε να χρησιμοποιείτε το ίδιο label με οποιοδήποτε από αυτά των Django contrib packages, όπως για παράδειγμαauth
,admin
ήmessages
.Μετακινήστε τον φάκελο
polls
μέσα στον φάκελοdjango-polls
.Δημιουργήστε ένα αρχείο
django-polls/README.rst
με το ακόλουθο περιεχόμενο:django-polls/README.rst===== Polls ===== Polls is a simple Django app to conduct Web-based polls. For each question, visitors can choose between a fixed number of answers. Detailed documentation is in the "docs" directory. Quick start ----------- 1. Add "polls" to your INSTALLED_APPS setting like this:: INSTALLED_APPS = [ ... 'polls', ] 2. Include the polls URLconf in your project urls.py like this:: url(r'^polls/', include('polls.urls')), 3. Run `python manage.py migrate` to create the polls models. 4. Start the development server and visit http://127.0.0.1:8000/admin/ to create a poll (you'll need the Admin app enabled). 5. Visit http://127.0.0.1:8000/polls/ to participate in the poll.
Δημιουργήστε ένα αρχείο
django-polls/LICENSE
. Η επιλογή μιας άδειας (license) είναι πέρα από τους σκοπούς αυτού του οδηγού, αλλά αρκεί να πούμε ότι κώδικας που έχει δημοσιευτεί χωρίς άδεια είναι άχρηστος. Το Django και πολλά άλλα συμβατα με το Django apps είναι διανεμημένα κάτω από την BSD άδεια. Ωστόσο, είστε ελεύθεροι να διαλέξετε μια της αρέσκειας σας. Κρατήστε στο μυαλό σας, όμως, ότι η επιλογή της αδείας επηρεάζει το ποιος θα μπορεί να χρησιμοποιήσει τον κώδικα σας.Επόμενο βήμα είναι να δημιουργήσουμε ένα αρχείο
setup.py
το οποίο θα παρέχει λεπτομέρειες σχετικά με το πως μπορεί κανείς να χτίσει (build) και να εγκαταστήσει (install) την εφαρμογή. Η πλήρης εξήγηση αυτού του αρχείου είναι πέρα από τους σκοπούς αυτού του οδηγού αλλά το εγχειρίδιο (documentation) του setuptools είναι αρκετά περιεκτικό. Δημιουργήστε ένα αρχείοdjango-polls/setup.py
με το ακόλουθο περιεχόμενο:django-polls/setup.pyimport os from setuptools import find_packages, setup with open(os.path.join(os.path.dirname(__file__), 'README.rst')) as readme: README = readme.read() # allow setup.py to be run from any path os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir))) setup( name='django-polls', version='0.1', packages=find_packages(), include_package_data=True, license='BSD License', # example license description='A simple Django app to conduct Web-based polls.', long_description=README, url='https://www.example.com/', author='Your Name', author_email='yourname@example.com', classifiers=[ 'Environment :: Web Environment', 'Framework :: Django', 'Framework :: Django :: X.Y', # replace "X.Y" as appropriate 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', # example license 'Operating System :: OS Independent', 'Programming Language :: Python', # Replace these appropriately if you are stuck on Python 2. 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Topic :: Internet :: WWW/HTTP', 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', ], )
Μόνο τα Python modules και τα packages περιλαμβάνονται στο package από προεπιλογή. Για να συμπεριλάβετε και πρόσθετα αρχεία, θα χρειαστεί να δημιουργήσουμε ένα αρχείο
MANIFEST.in
. Το εγχειρίδιο του πακέτου setuptools αναφέρεται σε αυτό το αρχείο με λεπτομέρεια. Για να συμπεριλάβετε τα templates, τοREADME.rst
και το αρχείοLICENSE
, δημιουργήστε ένα αρχείοdjango-polls/MANIFEST.in
με το ακόλουθο περιεχόμενο:django-polls/MANIFEST.ininclude LICENSE include README.rst recursive-include polls/static * recursive-include polls/templates *
Προτείνεται, παρόλο που είναι προαιρετικό, να συμπεριλάβετε ένα λεπτομερές εγχειρίδιο (documentation) με την εφαρμογή σας. Δημιουργήστε ένα κενό φάκελο
django-polls/docs
για μελλοντική προσθήκη του εγχειριδίου. Προσθέστε την ακόλουθη πρόσθετη γραμμή στο αρχείοdjango-polls/MANIFEST.in
:recursive-include docs *
Σημειώστε ότι ο φάκελος
docs
δεν θα συμπεριληφθεί στο package σας εκτός και αν προσθέσετε μερικά αρχεία μέσα. Σε περίπτωση που δεν το γνωρίζατε, πολλά Django apps παρέχουν το δικό τους documentation και online μέσα από ιστοσελίδες όπως η readthedocs.org.Προσπαθήστε να χτίσετε το πακέτο σας (build package) με την εντολή
python setup.py sdist
(τρέξτε την μέσα από τον φάκελοdjango-polls
). Αυτή η εντολή δημιουργεί έναν φάκελο με το όνομαdist
και χτίζει το νέο σας πακέτο με το όνομαdjango-polls-0.1.tar.gz
.
Για περισσότερες πληροφορίες σχετικά με το packaging, δείτε στο άρθρο της Python Tutorial on Packaging and Distributing Projects.
Χρησιμοποιώντας το δικό σας package¶
Από τη στιγμή που μετακινήσαμε τον φάκελο polls
έξω από το project, η εφαρμογή μας δεν δουλεύει πλέον, κάτι το οποίο είναι λογικό. Σε αυτή την παράγραφο θα εγκαταστήσουμε την εφαρμογή μας,``django-polls``, σαν ένα (τρίτο) πακέτο.
Εγκατάσταση ως βιβλιοθήκη χρήστη (user library)
Τα ακόλουθα βήματα εγκαθιστούν το πακέτο django-polls
ως μια βιβλιοθήκη χρήστη. Αυτό σημαίνει ότι το πακέτο θα εγκατασταθεί στον υπολογιστή για τον συγκεκριμένο χρήστη και όχι γενικά (global) για όλους τους χρήστες του συστήματος. Αυτή η εγκατάσταση έχει πολλά πλεονεκτήματα έναντι της γενικής (global) διότι μπορεί η εφαρμογή να χρησιμοποιηθεί σε συστήματα όπου δεν υπάρχουν δικαιώματα διαχειριστή ή να αποτρέψει την πρόσβαση στην εφαρμογή από άλλους χρήστες ή άλλες υπηρεσίες του συστήματος.
Σημειώστε ότι παρόλα τα πλεονεκτήματα των εγκαταστάσεων ανά χρήστη (per-user installations) η συμπεριφορά των εργαλείων του συστήματος μπορεί να επηρεαστεί για τον συγκεκριμένο χρήστη. Για την επίλυση τέτοιων καταστάσεων η χρήση ενός virtualenv
είναι όχι μόνο απαραίτητη αλλά και σταθερή (δείτε παρακάτω).
Για να εγκαταστήσετε το πακέτο σας, χρησιμοποιήστε το pip (το έχετε :ref:` ήδη εγκατεστημένο <installing-reusable-apps-prerequisites>`, σωστά?):
pip install --user django-polls/dist/django-polls-0.1.tar.gz
Με λίγη τύχη, το Django project σας θα λειτουργεί και πάλι όπως πριν. Τρέξτε τον server, ξανά, για να το επιβεβαιώσετε.
Για να απεγκαταστήσετε το πακέτο σας, χρησιμοποιήστε, πάλι το pip:
pip uninstall django-polls
Δημοσιεύοντας το app σας¶
Τώρα που έχουμε μετατρέψει σε package και τεστάρει την εφαρμογή django-polls
, είναι έτοιμη να διαμοιραστεί στον υπόλοιπο κόσμο! Αν αυτό δεν ήταν κάποιο παράδειγμα, θα μπορούσατε να:
Στείλετε με email το package σε κάποιον φίλο.
Να ανεβάσετε το package στην ιστοσελίδα σας.
Να ποστάρετε το package σε κάποιο public repository, όπως το Python Package Index (PyPI). Ο ιστότοπος packaging.python.org έχει έναν καλό οδηγό για αυτό το βήμα.
Εγκατάσταση Python packages με το virtualenv¶
Νωρίτερα, εγκαταστήσαμε την εφαρμογή ψηφοφορίας ως μια βιβλιοθήκη χρήστη (user library). Αυτό κρύβει μερικά μειονεκτήματα:
Η αλλαγή των βιβλιοθηκών χρηστών μπορεί να επηρεάσει άλλο Python software μέσα στο σύστημα σας.
Δεν θα είστε σε θέση να τρέξετε πολλαπλές εκδόσεις το ίδιου πακέτου (ή άλλων με το ίδιο όνομα).
Τυπικά, αυτές οι καταστάσεις, προκύπτουν μόνο αν διατηρείτε πολλαπλά Django projects. Σε τέτοιες περιπτώσεις, η καλύτερη λύση είναι να χρησιμοποιήσετε ένα virtualenv. Αυτό το εργαλείο σας επιτρέπει να διατηρείτε πολλαπλά απομονωμένα Python environments, όπου το καθένα έχει ένα δικό του αντίγραφο βιβλιοθηκών καθώς και namespace των packages. Ίσως να μπορεί να παρομοιαστεί με το virtualbox – πολλά λειτουργικά περιβάλλοντα όπου το καθένα είναι απομονωμένο από το άλλο.