bytes.cat

La wiki d'FP d'informàtica

Eines de l'usuari

Eines del lloc


django

Diferències

Ací es mostren les diferències entre la revisió seleccionada i la versió actual de la pàgina.

Enllaç a la visualització de la comparació

Ambdós costats versió prèvia Revisió prèvia
Següent revisió
Revisió prèvia
django [2024/01/02 10:39]
enric_mieza_sanchez [Pujar els arxius]
django [2024/04/07 23:41] (actual)
enric_mieza_sanchez [Versions]
Línia 18: Línia 18:
  
 {{tag> #FpInfor #Daw #DawMp07 #DawMp07Uf02 #DawMp07Uf2 #DawMp07Uf02 #Ciber #Ceti #CiberMp03 #CetiMp03 django framework python web DevOps }} {{tag> #FpInfor #Daw #DawMp07 #DawMp07Uf02 #DawMp07Uf2 #DawMp07Uf02 #Ciber #Ceti #CiberMp03 #CetiMp03 django framework python web DevOps }}
 +
  
 \\ \\
Línia 70: Línia 71:
  
 Visita el //admin panel// a ''http://localhost:8000/admin/'' Visita el //admin panel// a ''http://localhost:8000/admin/''
 +
 +\\
 +
 +===== ORM, models i migracions =====
 +**Un //Object-Relational Mapper// és una eina que facilita l'accés a dades mapejant les taules i relacions en objectes (classes) del llenguatge de programació**. Això permet una abstracció de la base de dades concreta que s'està emprant i no haver d'utilitzar SQL, sinó crides a mètodes dels objectes instanciats.
 +
 +Un **model**, en el context d'un ORM, **és una //class// que està mapejada a una taula de la base de dades**. Així, per exemple, es pot crear la següent //class// a l'arxiu ''models.py'' de Django:
 +
 +<code python>
 +from django.db import models
 +
 +class Llibre (models.Model):
 +    titol = models.CharField(max_length=100)
 +    autor = models.CharField(max_length=200)
 +    resum = models.TextField(null=True,blank=True)
 +    data_edicio = models.DateField()
 +</code>
 +
 +Per crear un llibre i guardar-lo a la taula, enlloc d'emprar SQL, amb el ORM faríem:
 +<code python>
 +llibre = Llibre()
 +llibre.titol = "El mag del Kremlin"
 +llibre.autor = "Giuliano da Empoli"
 +import datetime
 +llibre.data_edicio = datetime.datetime(2023, 3, 29)
 +# per persistir l'objecte a la BD cal cridar el mètode save()
 +llibre.save()
 +</code>
 +
 +En el context dels //frameworks// de desenvolupament, **una eina de migració gestiona les versions i evolució dels esquemes de les bases de dades**.
 +
 +Durant el desenvolupament convé planificar amb anterioritat l'esquema de la base de dades per tal que pateixi el mínim de modificacions. Cada cop que es modifica la base de dades hi ha un gran risc de que parts del codi deixin de funcionar o de que perdem dades en el canvi (migració) d'una versió de l'esquema a la següent. Malgrat tot, preveure totes les situacions es fa impossible i aplicar canvis a l'esquema de la base de dades es fa imprescindible, per molt que es vulgui minimitzar. L'ús d'eines de migració milloren aquesta gestió i permeten una transició ordenada i, sobretot, automatitzada, d'un esquema al següent.
 +
 +{{:django:migracions.png?600}}
 +
 +El mecanisme és simple: cal un arxiu de migració que realitzi els canvis a la BD a cada evolució. Cada migració pot implicar un canvi simple com afegir o esborrar una columna fins a grans canvis com afegir multitud de taules i relacions.
 +
 +Tenim dos exemples complementaris i paradigmàtics en la gestió de les migracions: els dels //frameworks// Django i Laravel:
 +  * En **Laravel** el desenvolupador ha d'escriure un script de migració per aplicar els canvis explícits a la base de dades, com eliminar una columna o crear noves taules i relacions.
 +  * En **Django** el desenvolupador modifica directament el model amb l'ORM. Amb la instrucció ''makemigrations'' l'arxiu de migració es genera automàticament. El //framework// analitza el codi del model actual i l'anterior, i genera les ordres adequades dins un script de migració.
 +
 +En el projecte que estavem desenvolupant, podem crear models i després realitzar les migracions executant:
 +  (env1) $ ./manage.py makemigrations
 +  (env1) $ ./manage.py migrate
 +
 +Veurem que ara **apareix un arxiu ''db.sqlite3'' a l'arrel del projecte** on s'hauran creat algunes taules, en particular ''users'' i ''groups'', que son objectes //builtin// de Django (venen predefinits tot i que es poden modificar). SQLite és un SGBD senzill per BD locals en un sol arxiu amb propòsits de desenvolupament (no és apta per a desplegament).
 +
 +Per visualitzar les taules podem crear un superusuari i entrar a l'//admin panel//:
 +  (env1) $ ./manage.py createsuperuser
 +  (env1) $ ./manage.py runserver
 +
 +Entrem a http://localhost:8000/admin/ amb l'usuari i contrasenya creats i podrem veure, crear i modificar usuaris i grups i les diferents característiques d'aquests.
 +
 +{{:django:django-admin-panel-1.png?500}}
  
 \\ \\
Línia 161: Línia 216:
 Hem de tenir en compte el cicle de vida de les versions de Django que fem servir. Les versions LTS són les //Long Term Service// que ens donaran cobertura durant més temps. Podem veure la [[https://www.djangoproject.com/download/#supported-versions|política de versions a la web de descàrrega de Django]]: Hem de tenir en compte el cicle de vida de les versions de Django que fem servir. Les versions LTS són les //Long Term Service// que ens donaran cobertura durant més temps. Podem veure la [[https://www.djangoproject.com/download/#supported-versions|política de versions a la web de descàrrega de Django]]:
  
-{{django-release-roadmap.png}}+{{https://static.djangoproject.com/img/release-roadmap.4cf783b31fbe.png}}
  
-Ara utilitzarem la 3.2 (LTS) però caldrà tenir cura d'actualitzar a la següent LTS (4.2) abans de que el suport de l'actual 3.2 finalitzi, com a màxim durant el primer trimestre de 2023.+Ara utilitzarem la 4.2 (LTS) però caldrà tenir cura d'actualitzar a la següent LTS (5.2) abans de que el suport de l'actual finalitzi
  
 \\ \\
Línia 201: Línia 256:
   * Afegir ''.env'' al ''.gitignore'' per tal de no pujar per error l'arxiu de variables d'entorn a producció.   * Afegir ''.env'' al ''.gitignore'' per tal de no pujar per error l'arxiu de variables d'entorn a producció.
   * Crear un arxiu d'exemple amb les variables d'entorn necessàries per facilitar la posada en marxa, però enlloc d'anomenar-lo ''.env'', que es diugui ''.env.example''    * Crear un arxiu d'exemple amb les variables d'entorn necessàries per facilitar la posada en marxa, però enlloc d'anomenar-lo ''.env'', que es diugui ''.env.example'' 
 +</WRAP>
 +
 +<WRAP tip>
 +Per fer una llista com ''ALLOWED_HOSTS'' dins el ''.env'' podem seguir [[https://stackoverflow.com/questions/60410625/get-django-allowed-hosts-env-variable-formated-right-in-settings-py|aquest fil amb possibles solucions]]. Potser la més elegant és fer-ho com a list:
 +<file python settings.py>
 +ALLOWED_HOSTS = env.list('ALLOWED_HOSTS')
 +</file>
 +
 +<file env .env>
 +ALLOWED_HOSTS=localhost,127.0.0.1,mysite.com
 +</file>
 </WRAP> </WRAP>
  
Línia 209: Línia 275:
  
 Per utilitzar MySQL caldrà instal·lar els binaris necessaris al sistema operatiu. Per a Ubuntu: Per utilitzar MySQL caldrà instal·lar els binaris necessaris al sistema operatiu. Per a Ubuntu:
-  $ sudo apt install libmysqlclient-dev gcc python3-dev python3-mysqldb+  $ sudo apt install libmysqlclient-dev python3-dev python3-mysqldb gcc pkgconf
  
 I també els connectors del virtualenv de Python: I també els connectors del virtualenv de Python:
Línia 284: Línia 350:
 Django no ha de servir mai arxius estàtics, ja que és menys eficient que el Web Server, que està pensat per a això específicament. El següent diagrama mostra com es durà a terme la posada en producció final: Django no ha de servir mai arxius estàtics, ja que és menys eficient que el Web Server, que està pensat per a això específicament. El següent diagrama mostra com es durà a terme la posada en producció final:
  
-{{diagrama_django_produccio.png?direct}}+{{:django:diagrama_django_produccio.png?direct}}
  
 <WRAP todo> <WRAP todo>
Línia 296: Línia 362:
 Comprova que accedint al panell d'administració ''/admin'' es visualitzen els CSS correctament. Comprova que accedint al panell d'administració ''/admin'' es visualitzen els CSS correctament.
  
-Troubleshooting (possibles errades): +**Troubleshooting (possibles errades):** 
-  * Revisa la configuració de ''mysite.conf'' de Nginx. +  * Revisa que has parat (stop) i inhabilitat Apache (possible col·lisió de ports). 
-  * Revisa l'arxiu ''/etc/polls''+  * Revisa la configuració de ''mysite.conf'' de Nginx. Millor que deixis només activada el //mysite// i desactivis la //default// (links simbòlics)
 +  * Revisa els errors de Nginx amb ''sudo journalctl -xeu nginx.service'' 
 +  * Si no veus el CSS fes CTRL+u , mira el codi font i clica un arxiu CSS aviam quin error et dona. 
 +  * Comprova que has afegit ''STATIC_ROOT = BASE_DIR 'static/''' al ''settings.css'' 
 +  * Comprova que has executat ''./manage.py collectstatic'' i que no dona errors. 
 +  * Si tens un ''Internal Server Error'' probablement hagis fet malament la comanda ''uwsgi'' (hauràs posat mysite.wsgi quan en realitat la teva carpeta es diu diferent de mysite).
  
 <WRAP important> <WRAP important>
Línia 305: Línia 376:
  
 </WRAP> </WRAP>
 +
 +
 +==== Engegant Django app amb Supervisor ====
  
 <WRAP todo> <WRAP todo>
django.1704191979.txt.gz · Darrera modificació: 2024/01/02 10:39 per enric_mieza_sanchez