Cele mai bune practici pentru structura directorului de lucru al proiectului Django. Server compact pentru aplicații Django

Această notă este o continuare a articolului despre scrierea unui bot telegram, în care voi încerca să acopăr cât mai detaliat subiectul implementării unei aplicații Django cu drepturi depline, deși mici, într-un mediu de producție pe Linux OS, Ubuntu 14.04 LTS. Până la sfârșitul articolului, vom avea un robot telegram cu drepturi depline care se rotește pe web și va primi comenzi de la utilizatorii acestui messenger.

Ce veți învăța după ce citiți nota:

  • Extinde Aplicația Django(și orice WSGI aplicație) găzduită de Digital Ocean într-un mediu Linux
  • Lucrați cu serverele web nginx și gunicorn
  • Gestionați procesele folosind utilitarul de supraveghere
  • Configurați virtualenv folosind pyenv
  • Lansați automat aplicația web chiar și după repornirea serverului

În septembrie 2015, am organizat o întâlnire Python în Almaty, unde am vorbit cu . În timpul discuției, am descris pe scurt ecosistemul web Python și am oferit o scurtă prezentare generală a instrumentelor populare. Din păcate, formatul de întâlnire nu a inclus analiză detaliată subiecte, așa că cei nou în domeniu trebuie de obicei să sape mai departe singuri. Astăzi voi încerca să umple acest gol și să aprofundez puțin mai mult în subiectul „fierbinte” al implementării aplicațiilor web în Python. În ciuda faptului că articolul se va concentra pe o aplicație Django, rețetele descrise vor fi relevante și pentru alte proiecte web dezvoltate în Python folosind cadre compatibile WSGI (Flask, Bottle, Pyramid, Falcon, web2py și așa mai departe).

În această notă mă voi desfășura la gazduire virtuala de Digital Ocean. Dacă vă înregistrați folosind acest link, atunci după confirmarea detaliilor dvs. de plată, contul dvs. va fi reîncărcat imediat cu 10 USD, pe care îi puteți cheltui pentru crearea de mici picături (servere virtuale) și exersați implementarea proiectelor web în Python. Vă spun imediat că nu trebuie să faceți totul pe o mașină de la distanță și, în general, să utilizați un furnizor de găzduire, vă puteți descurca cu o mașină virtuală locală, de exemplu, folosind VirtualBox (dar în acest caz va fi imposibil pentru a instala un webhook).

Crearea unui server virtual

După cum am menționat mai devreme, vom realiza implementarea pe unul dintre serverele virtuale DigitalOcean cu API-ul său puternic :)

Creați o picătură făcând clic pe „Creare droplet” în colțul din dreapta sus al panoului de control:

Alegem cel mai mic tarif pentru 5 USD pe lună cu sistem de operare Ubuntu 14.04.4 LTS la bordul viitoarei mașini virtuale.

Aproape întotdeauna aleg Frankfurt ca centru de date, deoarece am cel mai aproape cel mai bun ping. După completarea tuturor câmpurilor obligatorii, faceți clic pe butonul „Creați”. Picătura este creată în 60 de secunde, după care toate informațiile despre noua mașină virtuală necesare accesului sunt trimise la e-mail: adresa IP, login și parolă.

Ajustarea serverului

Actualizarea pachetelor:

# apt-get update # apt-get -y upgrade

# adduser django # adduser django sudo

Conectați-vă cu un utilizator nou django către server și toate celelalte comenzi sunt executate de sub acest utilizator.
Instalăm arsenalul necesar pentru a configura un mediu virtual prin Pyenv și pentru a construi cea mai recentă versiune de Python (2.7.11).

$ sudo apt-get install -y build-essential $ sudo apt-get install -y python-dev libreadline-dev libbz2-dev libssl-dev libsqlite3-dev libxslt1-dev libxml2-dev $ sudo apt-get install -y git

După aceea, instalăm Pyenv în sine. Puteți citi mai multe despre ce este Pyenv și despre cum să-l configurați:
Instalați cea mai recentă versiune de Python (Python 2.7.11):

$ pyenv install 2.7.11 Se descarcă Python-2.7.11.tgz... -> https://www.python.org/ftp/python/2.7.11/Python-2.7.11.tgz Se instalează Python-2.7.11 ... Python-2.7.11 instalat pe /home/django/.pyenv/versions/2.7.11

Comanda va dura ceva timp pentru a se finaliza (scriptul va descărca Python și îl va compila din sursă). Instalând un interpret Python separat, nu afectăm în niciun fel funcționarea celui de sistem în plus, cea mai recentă versiune LTS a Ubuntu (14.04) folosește versiunea 2.7.6, care are o serie de vulnerabilități grave, inclusiv un bug cu; SSL și, de asemenea, nu are suport pentru TLS 1.2

Clonăm depozitul cu proiectul Django:

$ cd ~ $ git clone https://github.com/adilkhash/planetpython_telegrambot.git $ cd planetpython_telegrambot/

$ pyenv virtualenv 2.7.11 telegram_bot $ pyenv local telegram_bot

Instalăm dependențe folosind managerul de pachete pip.

Pip install -r requirements.txt

Aplicația Django scrisă în prima parte a suferit modificări minore. În special, am transferat părțile modificabile ale codului într-un fișier special .env folosind biblioteca django-environ. Puteți vizualiza modificările folosind acest link.

Creați un fișier .env din șablon și completați setările necesare.

$ cd blog_telegram && mv .env-template .env && vi .env

În special, trebuie să schimbați modul DEBUG în False, să înregistrați un token pentru botul Telegram și să specificați o gazdă suplimentară separată prin virgule în ALLOWED_HOSTS. În cazul meu, ALLOWED_HOSTS arată astfel:

ALLOWED_HOSTS=127.0.0.1,bot.site

Adică am creat un subdomeniu suplimentar pe care va rula botul Telegram.

Configurarea unui certificat SSL

În articolul anterior, am scris că atunci când folosești apelul API setWehook, gazda trebuie să aibă un certificat SSL valid (Telegram permite și utilizarea certificatelor autosemnate). Vom crea certificatul prin serviciul gratuit de emitere a certificatelor SSL Let's Encrypt.

$ cd ~ && git clone https://github.com/letsencrypt/letsencrypt $ cd letsencrypt/ $ ./letsencrypt-auto certonly --standalone -d bot.site

Va trebui să specificați unele setări și să fiți de acord cu termenii și condițiile. După executarea cu succes a comenzilor, certificatele vor fi localizate în /etc/letsencrypt/live/bot.site/

Configurarea Nginx

Acum este timpul să instalați popularul HTTP serverul nginx care în cazul nostru va acționa ca un proxy (primiți solicitări de la clienți și le transmite mai departe urmând instrucțiunile din fișierul de configurare).

$ sudo apt-get install -y nginx $ cd /etc/nginx/sites-available/ $ sudo nano telegram_bot.conf

Completați fișier nou telegram_bot.conf cu următorul conținut:

Server ( ascultă 80; ascultă 443 ssl; nume_server bot..site/fullchain.pem; cheie_certificat ssl /etc/letsencrypt/live/bot..pem; locație / ( proxy_set_header Gazdă $http_host; proxy_redirect dezactivat; proxy_set_header X-Forwarded-Forwarded proxy_add_x_forwarded_for proxy_set_header X-Real-IP $remote_addr X-Scheme;

AVERTISMENT: Nu uitați să înlocuiți gazda bot.site de unul singur.

Înregistrăm noua noastră configurație în setările nginx și o repornim pentru ca modificările să intre în vigoare:

$ cd /etc/nginx/sites-enabled/ $ sudo ln -s ../sites-available/telegram_bot.conf telegram_bot.conf $ sudo service nginx restart

Ce tocmai am făcut?

  • Am înregistrat un certificat SSL valid pentru site-ul nostru web
  • Toate cererile care ajung la gazdă vor fi trimise prin proxy către viitoarea noastră aplicație Django, care, la rândul ei, ar trebui să ruleze pe portul 8001.
  • Transmitem anteturi HTTP suplimentare în fiecare solicitare (gazdă, adresa IP a clientului, schema https/http și așa mai departe). Puteți citi mai multe despre setările nginx.

Pentru a verifica succesul setărilor noastre, puteți rula aplicația django prin serverul de testare cu comanda runserver pe portul 8001 și mergeți la site:

$ cd ~/planetpython_telegrambot/ $ python manage.py runserver 8001

Deschide browserul și vezi (l-am deschis imediat prin https):

URL Not Found este un fenomen normal, deoarece avem doar 1 URL valid pentru lucrul direct cu Telegram - /planet/bot/ / (fără a lua în calcul setările de administrator Django).

Configurarea Gunicorn prin Supervisor

Este timpul să începeți configurarea unui server HTTP pregătit pentru producție Gunicorn, care, apropo, este scris în întregime în Python și s-a dovedit bine în luptă reală (apropo, în toate proiectele „live” folosesc această combinație specială: nginx+gunicorn)

Ce este Supervizorul?

Supraveghetor Acesta este un utilitar de gestionare a proceselor. „Monitorizează starea de sănătate” a proceselor tale demoni și, dacă acestea cad, încearcă să le ridice din nou. Dacă Gunicorn „cade” în timpul funcționării (eroare de sistem, faza greșită a lunii etc.), Supervizorul încearcă din nou „să-l ridice”, astfel încât performanța site-ului să nu sufere. Apropo, am de gând să scriu o scurtă notă despre acest utilitar, ca să zic așa, Supervisor Advanced Usage. Este de remarcat faptul că toate procesele care rulează în Supervisor trebuie să ruleze în modul prim-plan, astfel încât utilitarul să înțeleagă când ceva nu merge conform planului.

Mai întâi, să creăm un fișier de configurare pentru a rula Gunicorn în Supervisor. Conținutul său arată astfel:

Command=/home/django/.pyenv/versions/telegram_bot/bin/gunicorn blog_telegram.wsgi:application -b 127.0.0.1:8001 -w 1 --timeout=60 --graceful-timeout=60 --max-requests= 1024 directory=/home/django/planetpython_telegrambot/ user=django redirect_stderr=True stdout_logfile=/tmp/gunicorn.log stderr_logfile=/tmp/gunicorn_err.log autostart=true autorestart=true startsecs=10 stopwaits=991 priority=s

Salvați fișierul sub numele gunicorn.conf ( ~/planetpython_telegrambot/gunicorn.conf). Apropo, Gunicorn este inclus în dependențele proiectului nostru ( cerințe.txt) și din moment ce l-am instalat deja în mediul nostru, puteți afla calea fișierului executabil executând comanda în interiorul mediului virtual activat (activarea are loc automat când mergeți în directorul aplicației web din cauza prezenței fișierului Acolo .python-versiune creat prin pyenv local):

$pyenv care gunicorn

Conținutul fișierului de configurare pentru supervisord:

File=/tmp/telgram_bot_supervisord.sock logfile=/tmp/telgram_bot_supervisord.log logfile_maxbytes=50MB logfile_backups=10 loglevel=info pidfile=/tmp/telgram_bot_supervisord.pid nodaemon=false minfds=1024 minprocvisor_supervisors. : make_main_rpcinterface serverurl=unix:///tmp/telgram_bot_supervisord.sock files = /home/django/planetpython_telegrambot/gunicorn.conf

Salvați în ~/planetpython_telegrambot/supervisord.conf

$superd

Lansarea ar trebui să continue fără erori. Pentru a afla starea proceselor curente, rulați utilitarul supervisorctl:

$ supervisorctl gunicorn RUNNING pid 20901, uptime 0:04:18 supervisor>

Pentru a obține ajutor, puteți rula comanda help. Și pentru a obține informații despre comandă - ajutor. De exemplu:

Supraveghetor> ajuta la oprire Oprire oprire Oprire proces:* Opriți toate procesele dintr-un grup oprire Opriți procese multiple sau grupuri opri toate Opriți supervizorul tuturor proceselor>

După lansarea cu succes a Supervisor, site-ul ar trebui să fie disponibil online.

Pornire automată a aplicației web la repornire

Ce se întâmplă dacă serverul nostru virtual se repornește brusc? (eșec în centrul de date, probleme la mașina gazdă, admin strâmb încurcat etc.). În cazul unui astfel de scenariu, acum aplicația noastră nu va porni automat. Pentru a remedia acest lucru, trebuie să depunem un pic mai mult efort pentru a scrie un mic script, pe care îl vom plasa cu succes în mecanismul de pornire al sistemului de operare Ubuntu (distribuții asemănătoare Debian).

Ați auzit vreodată despre așa-numitele fișiere parvenite? Este scrierea unuia dintre ei pe care acum o vom face. Apropo, Upstart este considerat în prezent învechit și o tranziție completă la systemd este planificată în noile versiuni ale sistemului de operare Linux.

Descriere „Supervizor Botul Telegram handler de pornire a aplicației django" pornire la nivelul de rulare oprire la nivelul de rulare [!2345] respawn setuid django setgid django chdir /home/django/planetpython_telegrambot/ exec /home/django/.pyenv/versions/telegram_bot/bin/supervisord

Dosarul trebuie introdus în /etc/init/(în cazul meu i-am dat numele telegram_bot.conf). Dacă anterior toate lansările nu au cauzat probleme, atunci după repornirea sistemului, aplicația va fi lansată automat:

$ sudo shutdown -r acum

Acum trebuie să ne înregistrăm adresa URL pe partea Telegram folosind apelul API setWebhook:

Import telepot bot_token = "BOT_TOKEN" bot = telepot.Bot(bot_token) bot.setWebhook ("https://bot..format(bot_token=bot_token))

Aceasta completează configurarea botului. Trimiterea comenzilor către botul nostru @PythonPlanetBotși obținem răspunsuri adecvate :)

  • înregistrarea cererilor de la utilizatori într-un fișier
  • a mutat setările modificabile (modul de depanare, simbolul bot, cheia secretă) la variabilele de mediu prin fișiere .env folosind django-environ
  • au adăugat șabloane de fișiere de configurare pentru gunicorn, nginx și supervizor

Știu că chiar nu există calea cea buna. Cu toate acestea, mi-a fost dificil să creez o structură de directoare care să funcționeze bine și să rămână curată pentru fiecare dezvoltator și administrator. Majoritatea proiectelor de pe github au o structură standard. Dar nu arată o modalitate de a organiza alte fișiere și toate proiectele pe PC.

Care este mai bun mod convenabil organizați toate aceste directoare pe mașina de dezvoltare? Cum le numiți și cum vă conectați și să îl implementați pe server?

  • proiecte (toate proiectele la care lucrați)
  • fișiere sursă (aplicația în sine)
  • copie de lucru a depozitului (folosesc git)
  • mediu virtual (prefer să-l plasez lângă proiect)
  • rădăcină statică (pentru fișiere statice compilate)
  • rădăcină media (pentru fișierele media descărcate)
  • CITEȘTE-MĂ
  • LICENȚE
  • documentație
  • schițe
  • (exemplu de proiect care utilizează aplicația oferită de acest proiect)
  • (în cazul utilizării sqlite)
  • tot ce ai nevoie de obicei pentru a lucra cu succes la un proiect

Probleme pe care vreau sa le rezolv:

4 raspunsuri

Există două tipuri de proiecte Django pe care le am în directorul meu ~/projects/, ambele au o structură ușor diferită:

  • Site-uri offline
  • Aplicații conectate

Site offline

Cel mai adesea proiecte private, dar nu neapărat. De obicei arată astfel:

~/projects/project_name/ docs/ # documentation scripts/ manage.py # instalat în PATH prin setup.py project_name/ # project director (cel pe care django-admin.py îl creează) aplicații/ # conturi de aplicații specifice proiectului/ # cele mai multe aplicație frecventă, cu model de utilizator personalizat __init__.py ... setări/ # setări pentru diferite medii, vezi mai jos __init__.py production.py development.py ... __init__.py # conține versiunea proiectului urls.py wsgi.py static/ # șabloane de fișiere statice specifice site-ului/ # teste de șabloane specifice site-ului/ # teste specifice site-ului (mai ales cele din browser) tmp/ # excluse din git setup.py requirements.txt requirements_dev.txt pytest.ini ...

Setări

Setările principale sunt cele de producție. Alte fișiere (de exemplu staging.py, development.py) pur și simplu importă totul de la production.py și suprascriu doar variabilele necesare.

Există fișiere de setări separate pentru fiecare mediu, de ex. producție, dezvoltare. Am câteva proiecte pe care le-am testat (pentru tester), (ca verificare înainte de implementarea finală) și heroku (pentru implementare în heroku).

Cerințe

Mai degrabă am stabilit cerințele în setup.py direct. Numai cele necesare pentru mediul de dezvoltare/test le am requirements_dev.txt .

Unele servicii (de exemplu, Heroku) necesită requirements.txt în directorul rădăcină.

setup.py

Util atunci când implementați un proiect folosind setuptools. Adaugă manage.py la PATH, astfel încât să pot rula manage.py direct (oriunde).

Aplicații pentru proiecte specifice

Am folosit aceste aplicații în directorul nume_proiect/aplicații/ și le-am importat folosind importul relativ.

Șabloane/fișiere statice/locale/de test

Am plasat aceste șabloane și fișiere statice în șabloane globale/director static, mai degrabă decât în ​​interiorul fiecărei aplicații. Aceste fișiere sunt de obicei editate de oameni care nu au nevoie deloc de framework-ul sau codul de proiect python. Dacă sunteți un dezvoltator full stack care lucrează singur sau într-o echipă mică, puteți crea șabloane/director static pentru fiecare aplicație. Este într-adevăr doar o chestiune de gust.

Același lucru este valabil și pentru limbă, deși uneori este convenabil să creați un director local separat.

Testele sunt, de obicei, cel mai bine plasate în cadrul fiecărei aplicații, dar există de obicei o mulțime de teste de integrare/funcționale care testează mai multe aplicații care lucrează împreună, astfel încât un director de testare global are sens.

Directorul Tmp

Există un director temporar la rădăcina proiectului care este exclus din VCS. A folosit pentru a stoca fișiere media/statice și o bază de date sqlite în timpul dezvoltării. Totul din tmp poate fi șters în orice moment fără probleme.

Virtualenv

Prefer virtualenvwrapper și pun toate venv-urile în directorul ~/.venvs, dar îl puteți plasa în interiorul tmp/ pentru a-l păstra împreună.

Șablon de proiect

Am creat un șablon de proiect pentru această configurare, django-start-template

Implementare

Acest proiect este implementat după cum urmează:

Sursă $VENV/bin/activate export DJANGO_SETTINGS_MODULE=project_name.settings.production git pull pip install -r requirements.txt # Actualizați baza de date, fișiere statice, localități manage.py syncdb --noinput manage.py migrate manage.py collectstatic --noinput manage.py makemessages -a manage.py compilemessages # restart wsgi touch nume_proiect/wsgi.py

Puteți folosi rsync în loc de git , dar trebuie totuși să rulați un lot de comenzi pentru a vă actualiza mediul.

Am realizat recent o aplicație care îmi permite să rulez o singură comandă de control pentru a actualiza mediul, dar am folosit-o doar pentru un singur proiect și încă experimentez cu ea.

Schițe și schițe

O schiță a șabloanelor pe care le plasez în directorul global șabloane/. Cred că este posibil să creați un dosar/schițe în rădăcina proiectului, dar nu l-am folosit încă.

Aplicație conectată

Aceste aplicații sunt de obicei pregătite pentru publicare ca sursă deschisă. Am oferit un exemplu mai jos django-forme

~/projects/django-app/ docs/ app/ tests/ example_project/ LICENSE MANIFEST.in README.md setup.py pytest.ini tox.ini .travis.yml ...

Numele cataloagelor sunt clare (sper). Am plasat fișierele de testare în afara directorului aplicației, dar chiar nu contează. Este important să furnizați un README și setup.py, astfel încât pachetul să poată fi instalat cu ușurință prin pip.

Răspunsul meu se bazează pe propria mea experiență de lucru și în principal din cartea Two Matching Django, pe care o recomand cu căldură și unde puteți găsi o explicație mai detaliată a tuturor. Voi răspunde doar la câteva întrebări și orice îmbunătățire sau corectare ar fi binevenită. Dar pot exista performanțe mai bune pentru a atinge același obiectiv.

Proiecte
Am un folder principal în directorul meu personal unde văd toate elementele la care lucrez.

Fișiere sursă
Eu personal folosesc rădăcina proiectului django ca rădăcină de depozit a proiectelor mele. Dar cartea recomandă separarea ambelor lucruri. Cred că aceasta este cea mai bună abordare, așa că sper că îmi voi schimba treptat proiectele.

Project_repository_folder/ .gitignore Makefile LICENSE.rst docs/ README.rst requirements.txt project_folder/ manage.py media/ app-1/ app-2/ ... app-n/ static/ templates/ project/ __init__.py settings/ __init__ .py base.py dev.py local.py test.py production.py ulrs.py wsgi.py

Repertoriu
Git sau Mercurial par a fi cele mai multe sisteme populare controlul versiunilor printre dezvoltatorii Django. Și cele mai populare servicii de găzduire de rezervă sunt GitHub și Bitbucket.

Mediu virtual
Folosesc virtualenv și virtualenvwrapper. După instalarea celui de-al doilea, trebuie să configurați directorul de lucru. Mine se află în directorul my/home/envs, deoarece acest lucru este recomandat în ghidul de instalare virtualenvwrapper. Dar nu cred că cel mai important este locul unde este plasat. Cel mai important lucru atunci când lucrezi cu medii virtuale- actualizați fișierul requirements.txt.

Pip freeze -l > requirements.txt

Rădăcină statică
Dosarul proiectului

Root Media
Dosarul proiectului

CITEȘTE-MĂ
Rădăcină de depozit

LICENȚĂ
Rădăcină de depozit

Documentație
Rădăcină de depozit. Aceste pachete Python vă pot ajuta să vă simplificați documentația:

Schițe

Exemple

Bază de date

Nu-mi place să creez un nou director de setări. Adaug doar fișiere numite settings_dev.py și settings_production.py, așa că nu trebuie să editez BASE_DIR. Abordarea de mai jos mărește structura implicită în loc să o schimbe.

Mysite/ # Project conf/ locale/ en_US/ fr_FR/ it_IT/ mysite/ __init__.py settings.py settings_dev.py settings_production.py urls.py wsgi.py static/ admin/ css/ # Stiluri back-end personalizate css/ # Fața proiectului fonturi/ imagini/ js/ sass/ staticfiles/ templates/ # Șabloanele de proiect includ/ footer.html header.html index.html myapp/ # Application core/ migrations/ __init__.py templates/ # Application templates myapp/ index.html static / myapp/ js/ css/ images/ __init__.py admin.py apps.py forms.py models.py models_foo.py models_bar.py views.py templatetags/ # Aplicație cu procesoare de context personalizate și etichete de șablon __init__.py context_processors.py templatetags/ __init__.py templatetag_extras.py gulpfile.js manage.py requirements.txt

pip install Django==2.1.7

Opțiunea 2: obțineți candidatul pentru lansare pentru 2.2

pip install --pre django

Opțiunea 3: Obțineți cea mai recentă versiune de dezvoltare

Cea mai recentă și mai bună versiune Django este cea care se află în depozitul nostru Git (sistemul nostru de control al reviziilor). Acest lucru este doar pentru utilizatorii experimentați care doresc să încerce modificările primite și să ajute la identificarea erorilor înainte de o lansare oficială. Obțineți-l folosind această comandă shell, care necesită Git:

git clone https://github.com/django/django.git

Informații suplimentare

Pentru cei nerăbdători:

  • Ultima lansare:
    Sume de control:
    Note de lansare:
  • Previzualizarea lansării:
    Sume de control:
    Note de lansare:

Care versiune este mai buna?

Îmbunătățim Django aproape în fiecare zi și ne pricepem destul de bine la păstrarea stabilă a codului. Astfel, utilizarea celui mai recent cod de dezvoltare este o modalitate sigură și ușoară de a obține acces la funcții noi pe măsură ce sunt adăugate. Dacă alegeți să urmați versiunea de dezvoltare, rețineți că vor exista ocazional modificări incompatibile cu înapoi. Veți dori să acordați o atenție deosebită comitărilor urmărind Django pe GitHub sau abonându-vă la django-updates.

Dacă sunteți doar în căutarea unei ținte de implementare stabilă și nu vă deranjează să așteptați următoarea versiune, veți dori să rămâneți cu cea mai recentă versiune oficială (care va include întotdeauna note detaliate despre orice modificări pe care va trebui să le faceți în timpul actualizării).

Lansări anterioare

  • Django 2.0.13:
    Sume de control:
    Note de lansare:
  • Django 1.11.20 (LTS):
    Sume de control:
    Note de lansare:
  • Traducere

În acest ghid, ne vom uita la principalele greșeli pe care le fac dezvoltatorii Django și vom învăța cum să le evităm. Articolul poate fi util chiar și dezvoltatorilor cu experiență, deoarece aceștia fac și greșeli precum suportul fiind prea scump setări mari sau conflicte de nume în resurse statice.


Django este un cadru Python gratuit, bazat pe web, open source, care ajută la rezolvarea problemelor comune de dezvoltare. Vă permite să creați aplicații flexibile, bine structurate. Django are multe din cutie capabilități moderne. De exemplu, pentru mine, funcții precum Admin, Object Relational Mapping (ORM), Routing și Templating fac din Django prima mea alegere atunci când aleg un set de instrumente de dezvoltare. Crearea unei aplicații necesită mult efort și, deși îmi place ceea ce fac, ca orice dezvoltator, vreau să petrec cât mai puțin timp posibil pe sarcini de rutină. Django ajută foarte mult în acest sens, fără a vă obliga să sacrificați flexibilitatea aplicației.


Caracteristica ucigașă a Django este o interfață de administrare puternică, configurabilă, care este generată automat (automagie?) pe baza schemei modelului și modelelor de administrare. Chiar te simți ca un vrăjitor. Folosind interfața Admin, utilizatorul poate configura multe lucruri, inclusiv o listă de control al accesului (ACL), permisiuni și acțiuni la nivel de rând, filtre, comenzi, widget-uri, formulare, asistență URL suplimentară și multe altele. Cred că fiecare aplicație are nevoie de un panou de administrare. Este doar o chestiune de timp până când aplicația dvs. principală are nevoie de un astfel de panou. În Django este creat rapid și convenabil.


Django are, de asemenea, un ORM puternic, care funcționează imediat cu toate bazele de date majore. Este „leneș”: spre deosebire de alte ORM-uri, accesează baza de date numai după cum este necesar. Are suport pentru instrucțiuni SQL de bază (și funcții) pe care le puteți utiliza din codul sursă Python, împreună cu toate celelalte caracteristici ale limbajului.
Django are un motor de șabloane foarte flexibil și puternic. Sunt disponibile multe filtre și etichete standard și, de asemenea, vă puteți crea propriile filtre. Django acceptă alte motoare precum șabloane personalizate, oferă un API pentru o integrare ușoară cu alte motoare folosind funcții standard de comenzi rapide pentru procesarea șabloanelor.


Cadrul are multe altele oportunități importante ca un router URL care analizează cererile primite și generează URL-uri noi pe baza schemei de rutare. În general, Django este o plăcere de utilizat și, atunci când aveți nevoie de ajutor, citiți documentația.

Greșeala #1: Utilizarea mediului global Python pentru dependențe de proiect

Nu utilizați mediul global Python pentru dependențele proiectului dvs., deoarece poate provoca conflicte de dependență. Python nu poate funcționa cu mai multe versiuni de pachete în același timp. Aceasta va deveni o problemă dacă diverse proiecte avem nevoie de versiuni diferite, incompatibile ale aceluiași pachet.


Această greșeală este făcută de obicei de către nou-veniți la dezvoltarea Python și Django care nu sunt conștienți de caracteristicile de izolare ale mediului Python.


Există multe modalități de a izola mediul, cele mai comune sunt:

  • virtualenv: pachet Python care generează folderul de mediu. Conține un script pentru (de)activarea mediului și gestionarea pachetelor instalate în acesta. Aceasta este metoda mea preferată și cea mai ușoară. De obicei creez un mediu apropiat de folderul proiectului.
  • virtualenvwrapper: Un pachet Python care instalează global și oferă acces la un set de instrumente pentru crearea/ștergerea/activarea mediilor virtuale etc. Toate mediile sunt stocate într-un singur folder (pot fi suprascrise folosind variabila WORKON_HOME). Nu văd niciun avantaj în utilizarea virtualenvwrapper în loc de virtualenv .
  • Mașini virtuale: Nu există o izolare mai bună decât o întreagă mașină virtuală dedicată aplicației dvs. Există o mulțime de instrumente disponibile, cum ar fi VirtualBox (gratuit), VMware, Parallels și Proxmox (preferatul meu, există versiune gratuită). Atunci când este combinată cu un instrument de automatizare a mașinii virtuale precum Vagrant, aceasta poate fi o soluție foarte puternică.
  • Containere: În ultimii ani, am folosit Docker în aproape fiecare proiect, mai ales în proiecte noi pornind de la zero. Docker este un instrument incredibil cu o mulțime de funcții. Există o mulțime de opțiuni disponibile pentru a-l automatiza. instrumente de la terți. Docker are stocarea în cache a straturilor, ceea ce permite recrearea extrem de rapidă a containerelor. În acestea, folosesc un mediu global Python, deoarece fiecare container are propriul său sistem de fișiere și proiectele sunt izolate la un nivel înalt. Docker permite noilor membri ai echipei să înceapă mai repede un proiect, mai ales dacă au experiență cu tehnologia.

Greșeala #2: lipsesc legăturile de dependență în requirements.txt

Fiecare proiect nou Python ar trebui să înceapă cu un fișier requirements.txt și un nou sandbox. De obicei, ați folosi pip/easy_install pentru a instala toate pachetele, fără a uita requirements.txt . De obicei mai ușor ( Pot fi, mai corect) implementează proiecte pe servere sau pe mașinile membrilor echipei.


De asemenea, este important să faceți în fișierul requirements.txt legare(pin) versiuni specifice ale dependențelor dvs. De obicei versiuni diferite pachetele oferă module, funcții și parametri de funcționare diferiți. Chiar și în versiunile minore, modificările dependenței pot fi de așa natură încât să vă distrugă pachetul. Aceasta este o problemă foarte serioasă dacă aveți un proiect live și intenționați să-l implementați în mod regulat, deoarece fără controlul versiunilor sistemul dvs. de compilare va instala întotdeauna cel mai recent versiune disponibilă pachet.


În producție, executați întotdeauna legarea pachetelor! Folosesc un instrument foarte bun pentru asta, pip-tools. Oferă un set de comenzi pentru a ajuta la gestionarea dependențelor. Instrumentul generează automat requirements.txt , care conține nu doar dependențele dvs., ci întregul arbore, adică dependențele dependențelor dvs.


Uneori trebuie să actualizați unele pachete din lista de dependențe (de exemplu, doar un cadru sau un utilitar). Dacă recurgeți la pip freeze, nu știți ce dependențe sunt folosite de ce pachete și, prin urmare, nu le puteți actualiza. Instrumentul pip-tools conectează automat pachetele în funcție de dependențele pe care le legați și, prin urmare, decide automat ce pachete trebuie actualizate. Și datorită comentariilor folosite în requirements.txt, știți întotdeauna ce pachet provine din ce dependență.


Dacă ești și mai atent, poți face copii de siguranță ale fișierelor sursă ale dependențelor tale. Stocați o copie în sistemul dvs. de fișiere, folderul Git, folderul S3, FTP, SFTP - oriunde o aveți la îndemână. Există situații în care eliminarea unui pachet relativ mic rupe un număr mare de pachete în npm. Pip vă permite să descărcați toate dependențele necesare ca fișiere sursă. Citiți mai multe despre acest lucru rulând pip help download .

Greșeala nr. 3: Folosirea funcțiilor Python de modă veche în loc de Vizualizări bazate pe clasă

Uneori este logic să utilizați funcții Python mici în fișierul views.py al aplicației dvs., în special pentru vizualizările de testare sau utilitare. Dar, de obicei, aplicațiile trebuie să utilizeze Vizualizări bazate pe clasă (CBV).


CBV-urile sunt reprezentări cu scop general care oferă clase abstracte, implementând sarcini comune de dezvoltare web. CBV-urile sunt create de profesioniști și acoperă cele mai căutate comportamente. Au un API frumos structurat, iar CBV vă va oferi oportunitatea de a vă bucura de toate beneficiile OOP. Codul tău va fi mai curat și mai lizibil. Uitați de dificultățile de utilizare specificații standard Funcții de vizualizare Django pentru crearea de liste, operațiuni CRUD, procesare formulare etc. Puteți extinde pur și simplu CBV-ul corespunzător pentru vizualizarea dvs. și suprascrieți funcțiile sau proprietățile clasei care configurează comportamentul vizualizării (de obicei, o funcție returnează o proprietate și puteți adăugați-i orice logică care vă poate transforma codul în spaghete dacă utilizați funcții de vizualizare în loc de CBV).


De exemplu, puteți utiliza diferite mix-uri în proiectul dvs. care redefinesc principalele modele de comportament CBV: crearea de contexte de vizualizare, verificarea autorizației la nivel de rând, crearea automată a căilor de șablon pe baza structurilor aplicației, integrarea caching-ului inteligent și multe altele.


Am creat un pachet Django Template Names care standardizează numele șabloanelor pentru vizualizările dvs. pe baza numelui aplicației și a clasei de vizualizare. Îl folosesc în fiecare zi și economisesc mult timp atunci când aleg nume. Doar introduceți mixin-ul în CBV - clasa Detail (TemplateNames, DetailView): - și va începe să funcționeze! Desigur, puteți suprascrie funcțiile mele și puteți adăuga șabloane mobile receptive, alte șabloane de agenți de utilizator sau orice altceva.

Greșeala nr. 4. Scrierea vederilor „grasă” și a modelelor „subțiri” (slăbite).

Dacă logica aplicației a fost mutată de la model la vederi, aceasta înseamnă că vederile conțin cod care aparține modelului. Adică reprezentările devin „groase”, iar modelul devine „subțire”.


Dar trebuie să scrieți modele „groase” și reprezentări „subțiri”.


Împărțiți logica în metode mici în model. Acest lucru le va permite să fie utilizate în mod repetat și din mai multe surse (interfață de utilizare back-end, interfață de utilizare front-end, puncte finale API, vizualizări multiple). Este nevoie de doar câteva linii de cod și nu trebuie să copiați-lipiți o grămadă de linii. Data viitoare când scrieți funcționalitate pentru a trimite un e-mail unui utilizator, extindeți modelul cu o funcție de e-mail, în loc să scrieți logica în controler.


Acest lucru va face codul dvs. mai testabil, deoarece puteți testa logica E-mailîntr-un singur loc, în loc să o faci în fiecare controler. Citiți mai multe despre această problemă în Cele mai bune practici Django. Soluția este simplă: scrieți modele „groase” și reprezentări „subțiri”. Începeți să faceți acest lucru în următorul proiect sau refactorizați-l pe cel actual.

Greșeala nr. 5. Fișier de setări uriaș și neîndemânatic

Chiar și fișierul de setări al unui nou proiect Django conține multe dintre aceste setări. Și în proiectele reale, fișierul crește la peste 700 de linii, care sunt greu de întreținut, mai ales atunci când mediile de dezvoltare, producție și punere în scenă au nevoie de configurații diferite.


Puteți împărți manual fișierul de configurare și puteți crea încărcătoare separate, dar vreau să recomand pachetul excelent și bine testat Django Split Settings Python pe care l-am coautor.


Pachetul oferă două funcții - opționale și includ - care acceptă metacaracterele pentru căi și importă fișierele de configurare in acelasi context. Acest lucru facilitează crearea de configurații prin declararea intrărilor de configurare în fișierele încărcate anterior. Pachetul nu afectează în niciun fel performanța Django și poate fi folosit în orice proiect.


Iată un exemplu de configurație minimă:


din split_settings.tools import optional, include include("components/base.py", "components/database.py", "components/*.py", # proiectul diferite setări de mediu optional("envs/devel/*.py "), optional("envs/production/*.py"), optional ("envs/staging/*.py"), # pentru orice setări locale optional('local_settings.py"),)

Greșeala #6: Aplicație all-in-one, structură slabă a aplicației și plasarea incorectă a resurselor

Orice proiect Django constă din mai multe aplicații. În terminologia Django, o aplicație este un proiect Python care conține cel puțin fișiere __init__.py și models.py. În versiunile recente ale Django models.py nu mai este necesar, este suficient doar __init__.py.


Aplicațiile Django pot conține module Python, module specifice Django (vizualizări, URL-uri, modele, panou de administrare, formulare, etichete șabloane etc.), fișiere statice, șabloane, migrări de baze de date, comenzi de control, teste unitare etc. Trebuie să vă spargeți aplicație monolitică în aplicații mici, reutilizabile, cu o logică simplă.


Ar trebui să puteți descrie pe deplin scopul aplicației în una sau două propoziții scurte. De exemplu: „Permite utilizatorului să se înregistreze și să își activeze contul prin poștă.”



  • Fișiere statice: proiect/aplicații/nume aplicație/static/nume aplicație/
  • Etichete de șablon: project/apps/appname/templatetags/appname.py
  • Fișiere șablon: proiect/aplicații/nume aplicație/șabloane/nume aplicație/

Prefixați întotdeauna numele aplicațiilor cu nume de subfolder, deoarece toate folderele statice sunt combinate într-unul singur. Și dacă două sau mai multe aplicații au un fișier js/core.js, atunci ultima aplicație din sets.INSTALLED_APPLICATIONS le va înlocui pe toate anterioare. Odată am întâlnit o astfel de eroare în proiectul meu și am petrecut aproximativ șase ore depanând până mi-am dat seama că un alt dezvoltator mi-a suprascris static/admin/js/core.js , așa că membrii echipei au implementat un panou SPA de administrare personalizat și au dat fișierelor lor următoarele aceleasi nume.


Iată un exemplu de structură pentru o aplicație portal care conține multe resurse și module Python.


root@c5b96c395cfb:/test# tree project/apps/portal/ project/apps/portal/ ├── __init__.py ├── admin.py ├── apps.py ├── ├── management ├── ├── management └── comenzi │ ├── __init__.py │ └── update_portal_feeds.py ├── migrații │ └── __init__.py └─── modele └── ── portal │ ├── css │ ├ ── img │ └── js ├── templates │ └── portal │ └── index.html ├── templatetags │ ├── portal py ├── teste.py ├ ─ ─ urls.py └── views.py 11 directoare, 14 fișiere

Datorită acestei structuri, puteți oricând să exportați aplicația într-un alt pachet Python și să o utilizați din nou. Puteți chiar să îl publicați în PyPi ca pachet open source sau să îl mutați într-un alt folder. Veți ajunge cu ceva ca această structură de proiect:


root@c5b96c395cfb:/test# arbore -L 3 . ├── implementați │ ├── chef │ └── docker │ ├── dezvolta │ └── producție ├── documente ├──────── ├── proiect │ ├── __init__.py │ ├── aplicații │ │ ├── auth │ │ ├── blog │ │ ├── întrebări frecvente │ │ │ portal │ │ ─│ │ │ └── utilizatori │ ├── conf │ ├── settings.py │ ├── static │ ├── șabloane │ ├── urls.py │ └── wsgi.py └── static └── admin ───s ── ├── fonturi ├── img └── js 25 directoare, 5 fișiere

Desigur, proiectul real va fi mai complex, dar această structură simplifică și face multe aspecte mai transparente.

Greșeala #7: STATICFILES_DIRS și STATIC_ROOT îi încurcă pe nou-veniți la dezvoltarea Django

Fișierele statice sunt active care nu se modifică pe măsură ce aplicația este utilizată. De exemplu, JavaScript, CSS, imagini, fonturi etc. În Django, acestea sunt „acumulate” într-un director public în timpul implementării.


În modul de dezvoltare - python manage.py runserver - Django caută fișiere statice utilizând setarea STATICFILES_FINDERS. În mod implicit, încearcă să găsească fișierul solicitat în folderele listate în STATICFILES_DIRS. Dacă nu îl găsește, caută folosind django.contrib.staticfiles.finders.AppDirectoriesFinder , care verifică folderul static al fiecărei aplicații instalate în proiect. Acest design vă permite să scrieți aplicații reutilizabile care vin cu propriile fișiere statice.


În producție, distribuiți date statice printr-un server web separat, cum ar fi nginx. Nu știe nimic despre structura aplicației proiectului Django sau în ce foldere sunt distribuite fișierele dvs. statice. Din fericire, Django ne oferă o comandă de gestionare a colectării statice - python manage.py collectstatic - care trece prin STATICFILES_FINDERS și copiază toate fișierele statice din folderele statice ale aplicației, precum și din folderele enumerate în STATICFILES_DIRS, în cel în care specificați directorul STATIC_ROOT. Acest lucru vă permite să rezolvați resursele ca date statice folosind aceeași logică ca serverul Django în modul de dezvoltare și să colectați toate fișierele statice într-un singur loc pentru serverul web.


Nu uitați să rulați collectstatic în mediul dvs. de producție!

Greșeala #8: Utilizarea implicită STATICFILES_STORAGE și încărcătoarele de șabloane Django în producție

Să vorbim despre managementul activelor în mediul de producție. Putem oferi cel mai bun UX dacă folosim politica „activele nu expiră niciodată” (puteți citi mai multe despre aceasta). Aceasta înseamnă că toate fișierele noastre statice trebuie să fie stocate în cache de browsere timp de săptămâni, luni sau chiar ani. Cu alte cuvinte, utilizatorii trebuie să descarce resurse doar o singură dată!


O idee bună și poate fi implementată în doar câteva rânduri în configurația nginx pentru folderul nostru cu fișiere statice. Dar ce zici de a verifica dacă memoria cache este actualizată? Dacă un utilizator descarcă o singură dată resursa noastră, ce se întâmplă dacă actualizați sigla, fonturile, JavaScript sau culoarea textului din meniu? Pentru a rezolva această problemă, trebuie să generați adrese URL și nume unice pentru fiecare fișier static de fiecare dată când implementați!


Pentru a face acest lucru, puteți utiliza ManifestStaticFilesStorage ca STATICFILES_STORAGE (ai grijă, hashing-ul este activat doar în modul DEBUG=false) și rula comanda collectstatic. Acest lucru va duce la o reducere a numărului de solicitări de resurse de la site-ul dvs. de producție și va face ca acesta să fie redat mult mai rapid.


O caracteristică interesantă a Django este încărcătorul de șabloane în cache. Nu reîncarcă și analizează fișierele șablon de fiecare dată când este redat. Analiza șabloanelor este o operațiune foarte costisitoare și necesită multe resurse de calcul. În mod implicit, șabloanele Django sunt analizate la fiecare cerere, ceea ce este rău, mai ales în producție, unde mii de solicitări pot fi procesate într-o perioadă scurtă de timp.


În secțiunea de configurare cached.Loader puteți găsi bun exempluși detalii despre soluția problemei. Nu utilizați încărcătorul în modul de dezvoltare deoarece nu reîncarcă șabloanele analizate din sistemul de fișiere. Va trebui să reporniți proiectul folosind python manage.py startapp ori de câte ori șablonul se schimbă. Acest lucru poate fi enervant în timpul dezvoltării, dar este ideal pentru un mediu de producție.

Greșeala #9: Python pur pentru utilitare sau scripturi

Django are o caracteristică grozavă - comenzile de control. Folosiți-le în loc să reinventați roata scriind scripturi Python pur pentru utilitățile proiectului dvs.


Consultați și pachetul Django Extensions, care este o colecție de extensii personalizate pentru Django. Poate cineva a implementat deja comenzile tale! Există multe comenzi țintă comune.

Greșeala nr. 10. Construcția de biciclete

Există mii de soluții gata făcute pentru Django și Python. Consultați motoarele de căutare înainte de a scrie ceva care nu este deloc unic. Probabil că există deja o soluție potrivită.


Nu este nevoie să complici lucrurile. În primul rând, să mergem pe Google! Instalați pachetul de calitate pe care îl găsiți, configurați, extindeți și integrați în proiectul dvs. Și dacă este posibil, contribuiți la open source.


Iată o listă cu propriile mele pachete Django pentru a începe:

  • Adresa URL pentru macrocomenzi Django: facilitează scrierea (și citirea) modelelor URL în aplicațiile Django folosind macrocomenzi.
  • Nume șabloane Django: un mic mixin care vă ajută să standardizați cu ușurință numele șabloanelor dvs. CBV.
  • Setări Django Split: Vă permite să distribuiți setările Django în mai multe fișiere și directoare. Ignoră și modifică cu ușurință setările. Folosește caractere metalice în căile fișierelor și marchează fișierele de configurare ca opționale.

Nu te repeta (USCAT)!


Sunt un susținător al conceptului DRY, așa că am creat scheletul Django - instrument la îndemână cu o serie de caracteristici frumoase din cutie:

  • Dezvoltare/producție Imagini Docker gestionate de docker-compose, permițând orchestrarea ușoară cu o listă de containere.
  • Un script Fabric simplu pentru implementare în producție.
  • Configurare pentru pachetul Django Split Settings cu setări de bază de date și surse locale.
  • Integrat în proiectul Webpack - când rulați comanda collectstatic, Django va colecta doar folderul dist.
  • Toate setările și caracteristicile de bază Django sunt configurate, cum ar fi șabloanele Django stocate în cache în producție, fișierele statice cu hashing, o bară de instrumente integrată pentru depanare, înregistrare etc.

Acesta este un schelet Django gata de utilizat pentru următorul dvs. proiect greenfield. Sper că vă economisește mult timp. Webpack are un minim configurație de bază, dar și fișiere .scss preconfigurate pentru procesare sunt instalate în el folosind SASS.

Etichete:

  • piton
  • django
  • nimeni nu citește etichete
Adaugă etichete

Descrierea procesului de instalare rapidă a Django din panoul de control Plesk.

Acest articol este învechit și se referă la un panou Plesk care nu va mai fi acceptat.

„Pro” (cu acces SSH conectat), „Plus”, „VIP”, precum și în timpul accesului de testare la aceste tarife și oferă pentru a crea rapid un nou proiect Django. Pentru a face acest lucru aveți nevoie de:

  1. Conectați-vă la Panoul de control (veți primi acreditările de acces imediat după.)
  2. În meniul principal al panoului de control, selectați „Domenii”.
  3. Selectați domeniul pe care intenționați să instalați Django.
  4. În grupul „Aplicații și servicii”, selectați „Aplicații web”.
  5. Introduceți django în bara de căutare și apoi începeți instalarea.
  6. Citiți cu atenție acordul de licență după acord, este posibilă o instalare ulterioară.
  7. În secțiunea „Opțiuni de instalare”, selectați directorul țintă pentru instalarea aplicației.
  8. În secțiunea „Setări baze de date” trebuie să selectați tipul (Activat acest moment MySQL și PostgreSQL sunt acceptate), specificați numele de utilizator și parola bazei de date - acești parametri vor fi introduși automat în fișierul settings.py.
  9. Apoi, trebuie să introduceți datele de conectare, adresa de e-mail și parola de administrator, această parolă va fi folosită în continuare.
  10. la capitolul " Setari personale„La instalarea pachetului, aveți acces la setările Django pentru noul proiect, în special:
    • „Django Project Name” - numele proiectului Django care va fi creat.
    • „Nume director cu proiecte Django” - numele directorului în care vor fi localizate proiectele Django, acest director va fi localizat în folderul privat de pe site-ul dvs.
    • „Activați interfața de administrator” - când această opțiune este selectată, django este implementat cu secțiunea de administrare activată, baza de date este sincronizată, datele de conectare și parola de administrator sunt setate la valorile specificate mai sus.
    • „Propriul tău mediu virtual” - această opțiune presupune crearea propriei „instanțe” python, în timp ce aveți posibilitatea de a vă instala propriile module, care pot diferi de cele instalate pe găzduire atunci când sunt activate, spațiul pe disc ocupat de aplicație crește ușor;

După instalare aceasta aplicație, la http://nume_domeniu/director_instalare/ vor fi disponibile pagina standard Cu cea mai recentă versiune stabilă de Django instalată cu Python 2.6.2, este necesar acces ssh complet pentru operațiuni ulterioare și pentru efectuarea de acțiuni standard, de exemplu, gestionarea unui proiect prin manage.py. Acest serviciu este disponibil implicit pentru planurile tarifare „Plus” și „VIP” la tariful „Pro” este posibil să obțineți acces complet ssh prin extinderea tarifului cu o opțiune suplimentară prin sistemul de facturare. Dacă din anumite motive acest pachet nu îndeplinește cerințele proiectului dvs., puteți crea un proiect Django