Il 0% ha trovato utile questo documento (0 voti)
637 visualizzazioni232 pagine

Apprendimento Django-It

Questo documento fornisce una panoramica di Django e dei suoi principali concetti e funzionalità. Viene spiegato come creare un progetto Django di base e vengono introdotti concetti chiave come modelli, viste, URL e amministrazione. Vengono inoltre forniti esempi di utilizzo di funzionalità avanzate come ArrayField, HStoreField e integrazione con reti sociali.

Caricato da

Kirikù A
Copyright
© © All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Il 0% ha trovato utile questo documento (0 voti)
637 visualizzazioni232 pagine

Apprendimento Django-It

Questo documento fornisce una panoramica di Django e dei suoi principali concetti e funzionalità. Viene spiegato come creare un progetto Django di base e vengono introdotti concetti chiave come modelli, viste, URL e amministrazione. Vengono inoltre forniti esempi di utilizzo di funzionalità avanzate come ArrayField, HStoreField e integrazione con reti sociali.

Caricato da

Kirikù A
Copyright
© © All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Sei sulla pagina 1/ 232

Django

#django
Sommario
Di 1

Capitolo 1: Iniziare con Django 2

Osservazioni 2

Versioni 2

Examples 3

Avvio di un progetto 3

Concetti di Django 5

Un esempio di ciao mondo completo. 6

Ambiente virtuale 7

Python 3.3+ 7

Python 2 7

Attiva (qualsiasi versione) 8

In alternativa: usa virtualenvwrapper 8

In alternativa: usa pyenv + pyenv-viritualenv 8

Imposta il tuo percorso del progetto 9

Esempio di file singolo Hello World 9

Progetto di facile impiego con supporto Docker. 10

Struttura del progetto 10

Dockerfile 11

Comporre 11

nginx 12

uso 12

Capitolo 2: Aggregazioni di modelli 14

introduzione 14

Examples 14

Media, Minima, Massima, Somma da Queryset 14

Conta il numero di relazioni estere 14

GROUB PER ... COUNT / SUM Equivalente di Django ORM 15

Capitolo 3: Amministrazione 17
Examples 17

Cambia lista 17

Ulteriori stili CSS e script JS per la pagina di amministrazione 18

Gestione di chiavi esterne che fanno riferimento a tabelle di grandi dimensioni 19

views.py 20

urls.py 20

forms.py 20

admin.py 21

Capitolo 4: ArrayField - un campo specifico PostgreSQL 22

Sintassi 22

Osservazioni 22

Examples 22

Un ArrayField di base 22

Specifica della dimensione massima di un ArrayField 22

Interrogare per l'appartenenza a ArrayField con contiene 23

Nesting ArrayFields 23

Interrogazione per tutti i modelli che contengono elementi in un elenco con contained_by 23

Capitolo 5: Associazione di stringhe alle stringhe con HStoreField: un campo specifico Pos 24

Sintassi 24

Examples 24

Impostazione di HStoreField 24

Aggiunta di HStoreField al modello 24

Creazione di una nuova istanza di modello 24

Esecuzione di ricerche chiave 25

L'utilizzo contiene 25

Capitolo 6: Attività asincrone (sedano) 26

Osservazioni 26

Examples 26

Semplice esempio per aggiungere 2 numeri 26

Capitolo 7: Backend di autenticazione 28

Examples 28

Email di back-end di autenticazione 28


Capitolo 8: Comandi di gestione 29

introduzione 29

Osservazioni 29

Examples 29

Creazione ed esecuzione di un comando di gestione 29

Ottieni l'elenco dei comandi esistenti 30

Utilizzando django-admin invece di manage.py 31

Comandi di gestione incorporati 31

Capitolo 9: Come resettare le migrazioni di django 33

introduzione 33

Examples 33

Reimpostazione della migrazione di Django: eliminazione del database esistente e migrazion 33

Capitolo 10: Come usare Django con Cookiecutter? 34

Examples 34

Installazione e configurazione del progetto django con Cookiecutter 34

Capitolo 11: Configurazione del database 36

Examples 36

MySQL / MariaDB 36

PostgreSQL 37

sqlite 38

infissi 38

Django Cassandra Engine 39

Capitolo 12: CRUD in Django 41

Examples 41

** Esempio CRUD più semplice ** 41

Capitolo 13: Debug 46

Osservazioni 46

Examples 46

Utilizzo di Python Debugger (Pdb) 46

Utilizzando la barra degli strumenti Debug di Django 47

Usare "asserire False" 49

Considera di scrivere più documenti, test, log e asserzioni invece di usare un debugger 49
Capitolo 14: Distribuzione 50

Examples 50

Esecuzione dell'applicazione Django con Gunicorn 50

Distribuzione con Heroku 50

Distribuzione remota semplice fabfile.py 51

Usando Heroku Django Starter Template. 52

Istruzioni di distribuzione di Django. Nginx + Gunicorn + Supervisor su Linux (Ubuntu) 52

Nginx 53

GUNICORN 54

SUPERVISORE 54

Distribuzione locale senza impostazione di apache / nginx 55

Capitolo 15: Django dalla riga di comando. 57

Osservazioni 57

Examples 57

Django dalla riga di comando. 57

Capitolo 16: Django e reti sociali 58

Parametri 58

Examples 59

Modo semplice: python-social-auth 59

Utilizzando Django Allauth 62

Capitolo 17: Django Rest Framework 65

Examples 65

API di sola lettura barebone semplice 65

Capitolo 18: django-filtro 67

Examples 67

Usa il filtro Django con CBV 67

Capitolo 19: Esecuzione di Celery con Supervisor 68

Examples 68

Configurazione del sedano 68

SEDANO 68

Supervisore in esecuzione 69

Celery + RabbitMQ con Supervisor 70


Capitolo 20: Estensione o sostituzione del modello utente 72

Examples 72

Modello utente personalizzato con email come campo di accesso principale. 72

Usa l'email come username e sbarazzati del campo `username` 75

Estendi facilmente il modello utente di Django 77

Specificare un modello utente personalizzato 79

Fare riferimento al modello utente 80

Capitolo 21: F () espressioni 82

introduzione 82

Sintassi 82

Examples 82

Evitare le condizioni di gara 82

Aggiornamento di queryset in blocco 82

Esegui operazioni aritmetiche tra i campi 83

Capitolo 22: formsets 85

Sintassi 85

Examples 85

Formset con dati inizializzati e unitializzati 85

Capitolo 23: Fusi orari 87

introduzione 87

Examples 87

Abilita supporto fuso orario 87

Impostazione dei fusi orari della sessione 87

Capitolo 24: Gestori e Queryys personalizzati 89

Examples 89

Definire un manager di base usando Querysets e il metodo `as_manager` 89

select_related per tutte le query 90

Definisci gestori personalizzati 90

Capitolo 25: impostazioni 92

Examples 92

Impostazione del fuso orario 92

Accesso alle impostazioni 92


Utilizzo di BASE_DIR per garantire la portabilità delle app 92

Utilizzo delle variabili di ambiente per gestire le impostazioni tra i server 93

settings.py 93

Utilizzando più impostazioni 94

# 1 alternativo 95

N. 2 alternativo 95

Utilizzo di più file di requisiti 95

Struttura 95

Nascondere i dati segreti utilizzando un file JSON 96

Utilizzo di DATABASE_URL dall'ambiente 97

Capitolo 26: Integrazione continua con Jenkins 99

Examples 99

Script Pipeline di Jenkins 2.0+ 99

Script Pipeline Jenkins 2.0+, contenitori Docker 99

Capitolo 27: Internazionalizzazione 101

Sintassi 101

Examples 101

Introduzione all'internazionalizzazione 101

Impostare 101

settings.py 101

Marcare le stringhe come traducibili 101

Tradurre le stringhe 102

Traduzione Lazy vs Non-Lazy 102

Traduzione in modelli 103

Tradurre le stringhe 104

Noop use case 106

Insidie comuni 106

traduzioni sfocate 106

Stringhe multilinea 107

Capitolo 28: JSONField - un campo specifico PostgreSQL 108

Sintassi 108
Osservazioni 108

Concatenare query 108

Examples 108

Creazione di un campo JSON 108

Disponibile in Django 1.9+ 108

Creazione di un oggetto con dati in un campo JSON 109

Interrogazione dei dati di livello superiore 109

Interrogazione dei dati nidificati nei dizionari 109

Interrogare i dati presenti negli array 109

Ordinamento in base ai valori di JSONField 109

Capitolo 29: Le forme 111

Examples 111

Esempio ModelForm 111

Definire una forma di Django da zero (con i widget) 111

Rimozione di un campo modelForm in base alle condizioni di views.py 111

Upload di file con Django Forms 113

Convalida dei campi e impegno per modellare (Modifica e-mail utente) 115

Capitolo 30: Meta: linee guida per la documentazione 117

Osservazioni 117

Examples 117

Le versioni non supportate non richiedono menzioni speciali 117

Capitolo 31: middleware 118

introduzione 118

Osservazioni 118

Examples 118

Aggiungi dati alle richieste 118

Middleware da filtrare per indirizzo IP 119

Gestione globale delle eccezioni 120

Comprensione del nuovo stile del middleware Django 1.10 121

Capitolo 32: migrazioni 122

Parametri 122

Examples 122
Lavorare con le migrazioni 122

Migrazioni manuali 123

Migrazioni false 124

Nomi personalizzati per i file di migrazione 125

Risolvere i conflitti di migrazione 125

introduzione 125

Unione di migrazioni 126

Cambia un CharField in un ForeignKey 126

Capitolo 33: Modelli 128

introduzione 128

Examples 128

Creare il tuo primo modello 128

Applicazione delle modifiche al database (Migrazioni) 128

Creare un modello con relazioni 130

Query di base su Django DB 131

Un tavolo non gestito di base. 132

Modelli avanzati 133

Chiave primaria automatica 133

URL assoluto 133

Rappresentazione delle stringhe 134

Campo di lumaca 134

La classe Meta 134

Valori calcolati 134

Aggiunta di una rappresentazione di stringa di un modello 135

Model mixins 136

Chiave primaria UUID 137

Eredità 138

Capitolo 34: Processori di contesto 139

Osservazioni 139

Examples 139

Utilizzare un processore di contesto per accedere alle impostazioni.DEBUG nei modelli 139

Utilizzo di un processore di contesto per accedere alle voci del blog più recenti in tutti 139
Estendere i tuoi modelli 141

Capitolo 35: RangeFields: un gruppo di campi specifici di PostgreSQL 142

Sintassi 142

Examples 142

Compresi i campi dell'intervallo numerico nel modello 142

Impostazione per RangeField 142

Creazione di modelli con campi intervallo numerico 142

L'utilizzo contiene 142

Utilizzando contenuto_by 143

Usando la sovrapposizione 143

Usando Nessuna per indicare nessun limite superiore 143

Varia le operazioni 143

Capitolo 36: Registrazione 144

Examples 144

Accesso al servizio Syslog 144

Configurazione di registrazione di base di Django 145

Capitolo 37: Relazioni molti-a-molti 147

Examples 147

Con un modello passante 147

Relazione semplice da molti a molti. 148

Usando ManyToMany Fields 148

Capitolo 38: Riferimento del campo del modello 149

Parametri 149

Osservazioni 150

Examples 150

Campi numerici 150

BinaryField 153

CharField 153

DateTimeField 153

ForeignKey 154

Capitolo 39: Router di database 156

Examples 156
Aggiunta di un file di routing del database 156

Specifica di diversi database nel codice 157

Capitolo 40: Routing URL 158

Examples 158

Come Django gestisce una richiesta 158

Imposta lo spazio dei nomi URL per un'app riutilizzabile (Django 1.9+) 160

Capitolo 41: segnali 162

Parametri 162

Osservazioni 162

Examples 163

Estensione dell'esempio del profilo utente 163

Sintassi diversa per postare / pre un segnale 163

Come trovare se si tratta di un inserimento o di un aggiornamento nel segnale pre_save 164

Ereditare i segnali sui modelli estesi 164

Capitolo 42: set di query 166

introduzione 166

Examples 166

Domande semplici su un modello standalone 166

Query avanzate con oggetti Q 167

Riduci il numero di query su ManyToManyField (n + 1 problema) 167

Problema 167

Soluzione 168

Riduci il numero di query sul campo ForeignKey (n + 1 problema) 169

Problema 169

Soluzione 170

Ottieni SQL per il queryset di Django 171

Ottieni il primo e l'ultimo record da QuerySet 171

Query avanzate con oggetti F 171

Capitolo 43: Sicurezza 173

Examples 173

Protezione Cross Site Scripting (XSS) 173


Protezione da Clickjacking 174

Protezione da richiesta di cross-site Forgery (CSRF) 175

Capitolo 44: Struttura del progetto 177

Examples 177

Deposito> Progetto> Sito / Conf 177

Namespacing statico e file di modelli in applicazioni django 178

Capitolo 45: Tag e filtri modello 179

Examples 179

Filtri personalizzati 179

Tag semplici 179

Tag personalizzati avanzati usando il nodo 180

Capitolo 46: templating 183

Examples 183

variabili 183

Templating in Views basate su classi 184

Templating in viste basate sulle funzioni 184

Filtri modello 185

Impedisci che i metodi sensibili vengano richiamati nei modelli 186

L'utilizzo di {% estende%}, {% include%} e {% blocchi%} 186

sommario 186

Guida 187

Capitolo 47: Test unitario 189

Examples 189

Test: un esempio completo 189

Testare i modelli Django in modo efficace 190

Testare il controllo degli accessi nelle viste Django 191

Il database e i test 193

Limita il numero di test eseguiti 194

Capitolo 48: Transazioni di database 196

Examples 196

Transazioni atomiche 196

Problema 196
Soluzione 196

Capitolo 49: Uso di Redis con Django - Backend di cache 198

Osservazioni 198

Examples 198

Utilizzando django-redis-cache 198

Usando il django-redis 198

Capitolo 50: Viste basate sulla classe 200

Osservazioni 200

Examples 200

Viste basate sulla classe 200

views.py 200

urls.py 200

Dati contestuali 200

views.py 201

book.html 201

Elenco e dettagli 201

app / models.py 201

app / views.py 201

app / templates / app / pokemon_list.html 202

app / templates / app / pokemon_detail.html 202

app / urls.py 202

Creazione di forme e oggetti 203

app / views.py 203

app / templates / app / pokemon_form.html (estratto) 204

app / templates / app / pokemon_confirm_delete.html (estratto) 204

app / models.py 204

Esempio minimo 205

Viste basate sulla classe Django: esempio di CreateView 205

Una vista, più moduli 206

Capitolo 51: Visualizzazioni 208


introduzione 208

Examples 208

[Introduzione] Vista semplice (Hello World Equivalent) 208

Capitolo 52: Visualizzazioni generiche 209

introduzione 209

Osservazioni 209

Examples 209

Esempio minimo: viste funzionali e generiche 209

Personalizzazione delle viste generiche 210

Visualizzazioni generiche con Mixins 211

Capitolo 53: Widget del modulo 213

Examples 213

Semplice widget di inserimento del testo 213

Widget composito 213

Titoli di coda 215


Di
You can share this PDF with anyone you feel could benefit from it, downloaded the latest version
from: django

It is an unofficial and free Django ebook created for educational purposes. All the content is
extracted from Stack Overflow Documentation, which is written by many hardworking individuals at
Stack Overflow. It is neither affiliated with Stack Overflow nor official Django.

The content is released under Creative Commons BY-SA, and the list of contributors to each
chapter are provided in the credits section at the end of this book. Images may be copyright of
their respective owners unless otherwise specified. All trademarks and registered trademarks are
the property of their respective company owners.

Use the content presented in this book at your own risk; it is not guaranteed to be correct nor
accurate, please send your feedback and corrections to [email protected]

https://riptutorial.com/it/home 1
Capitolo 1: Iniziare con Django
Osservazioni
Django si autodefinisce "il framework web per perfezionisti con scadenze" e "Django rende più
facile creare migliori app Web in modo più rapido e con meno codice". Può essere visto come
un'architettura MVC. Al suo centro ha:

• un server Web leggero e autonomo per lo sviluppo e il test


• un sistema di serializzazione e validazione di moduli in grado di tradurre tra forme e valori
HTML adatti per l'archiviazione nel database
• un sistema di template che utilizza il concetto di ereditarietà preso in prestito dalla
programmazione orientata agli oggetti
• un framework di caching che può utilizzare uno qualsiasi dei vari metodi di cache per
supportare classi middleware che possono intervenire in varie fasi dell'elaborazione della
richiesta ed eseguire funzioni personalizzate
• un sistema di dispatcher interno che consente ai componenti di un'applicazione di
comunicare gli eventi tra loro tramite segnali predefiniti
• un sistema di internazionalizzazione, comprese le traduzioni delle componenti di Django in
una varietà di lingue
• un sistema di serializzazione in grado di produrre e leggere rappresentazioni XML e / o
JSON di istanze di modelli Django
• un sistema per estendere le funzionalità del motore di template
• un'interfaccia al framework di test unità integrato di Python

Versioni

Versione Data di rilascio

1.11 2017/04/04

1.10 2016/08/01

1.9 2015/12/01

1.8 2015/04/01

1.7 2014/09/02

1.6 2013/11/06

1.5 2013/02/26

1.4 2012-03-23

1.3 2011-03-23

https://riptutorial.com/it/home 2
Versione Data di rilascio

1.2 2010-05-17

1.1 2009-07-29

1.0 2008-09-03

Examples
Avvio di un progetto

Django è un framework di sviluppo web basato su Python. Django 1.11 (l'ultima versione stabile)
richiede l'installazione di Python 2.7 , 3.4 , 3.5 o 3.6 . Supponendo che pip sia disponibile,
l'installazione è semplice come eseguire il seguente comando. Tieni presente che, omettendo la
versione come mostrato di seguito, verrà installata l'ultima versione di django:

$ pip install django

Per installare una versione specifica di django, supponiamo che la versione sia django 1.10.5 ,
esegui il seguente comando:

$ pip install django==1.10.5

Le applicazioni Web create con Django devono risiedere all'interno di un progetto Django. È
possibile utilizzare il comando django-admin per avviare un nuovo progetto nella directory corrente:

$ django-admin startproject myproject

dove myproject è un nome che identifica in modo univoco il progetto e può essere composto da
numeri , lettere e caratteri di sottolineatura .

Questo creerà la seguente struttura di progetto:

myproject/
manage.py
myproject/
__init__.py
settings.py
urls.py
wsgi.py

Per eseguire l'applicazione, avviare il server di sviluppo

$ cd myproject
$ python manage.py runserver

Ora che il server è in esecuzione, visita http://127.0.0.1:8000/ con il browser web. Vedrai la

https://riptutorial.com/it/home 3
seguente pagina:

Per impostazione predefinita, il comando runserver avvia il server di sviluppo sull'IP interno sulla
porta 8000 . Questo server si riavvierà automaticamente quando apporti modifiche al tuo codice.
Ma nel caso si aggiungano nuovi file, sarà necessario riavviare manualmente il server.

Se si desidera modificare la porta del server, passarla come argomento della riga di comando.

$ python manage.py runserver 8080

Se si desidera modificare l'IP del server, passarlo insieme alla porta.

$ python manage.py runserver 0.0.0.0:8000

Nota che runserver è solo per le build di debug e test locali. I programmi server specializzati (come
Apache) dovrebbero sempre essere utilizzati in produzione.

Aggiunta di un'app Django

Un progetto Django di solito contiene più apps . Questo è semplicemente un modo per strutturare il
tuo progetto in moduli più piccoli e manutenibili. Per creare un'app, vai alla tua cartella di progetto
(dove manage.py è), ed esegui il comando startapp (cambia myapp in quello che vuoi):

python manage.py startapp myapp

Questo genererà la cartella myapp e alcuni file necessari per te, come models.py e views.py .

Per rendere Django consapevole di myapp , aggiungilo alle tue settings.py :

# myproject/settings.py

# Application definition
INSTALLED_APPS = [
...
'myapp',
]

La struttura di cartelle di un progetto Django può essere modificata in base alle tue preferenze. A

https://riptutorial.com/it/home 4
volte la cartella del progetto viene rinominata in /src per evitare di ripetere i nomi delle cartelle.
Una tipica struttura di cartelle si presenta così:

Concetti di Django

django-admin è uno strumento da riga di comando fornito con Django. Viene fornito con diversi
comandi utili per iniziare e gestire un progetto Django. Il comando è lo stesso di ./manage.py , con
la differenza che non è necessario essere nella directory del progetto. La variabile di ambiente
DJANGO_SETTINGS_MODULE deve essere impostata.

Un progetto Django è un codice Python che contiene un file di impostazioni Django. Un progetto
può essere creato dall'amministratore di Django tramite il comando django-admin startproject NAME
. manage.py il progetto ha un file chiamato manage.py al livello più alto e un file URL di root chiamato
urls.py manage.py è una versione specifica del progetto di django-admin e consente di eseguire
comandi di gestione su quel progetto. Ad esempio, per eseguire il progetto localmente, utilizzare
python manage.py runserver . Un progetto è costituito da app Django.

models.py Django è un pacchetto Python che contiene un file di modelli ( models.py per
impostazione predefinita) e altri file come URL e viste specifici dell'app. django-admin startapp NAME
può essere creata tramite il comando django-admin startapp NAME (questo comando dovrebbe
essere eseguito all'interno della directory del progetto). Affinché un'app faccia parte di un progetto,
deve essere inclusa nell'elenco INSTALLED_APPS in settings.py . Se hai usato la configurazione
standard, Django viene fornito con diverse app delle sue app preinstallate che gestiranno cose
come l' autenticazione per te. Le app possono essere utilizzate in più progetti Django.

Django ORM raccoglie tutti i modelli di database definiti in models.py e crea tabelle di database in
base a tali classi di modelli. Per fare ciò, innanzitutto, imposta il tuo database modificando

https://riptutorial.com/it/home 5
l'impostazione DATABASES in settings.py . Quindi, una volta definiti i modelli di database , eseguire
python manage.py makemigrations seguito da python manage.py migrate per creare o aggiornare lo
schema del database in base ai modelli.

Un esempio di ciao mondo completo.

Passaggio 1 Se hai già installato Django, puoi saltare questo passaggio.

pip install Django

Passaggio 2 Creare un nuovo progetto

django-admin startproject hello

Questo creerà una cartella chiamata hello che conterrà i seguenti file:

hello/
├── hello/
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py

Passaggio 3 All'interno del modulo hello (la cartella contenente __init.py__ ) crea un file
chiamato views.py :

hello/
├── hello/
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ ├── views.py <- here
│ └── wsgi.py
└── manage.py

e inserire il seguente contenuto:

from django.http import HttpResponse

def hello(request):
return HttpResponse('Hello, World')

Questa è chiamata funzione di visualizzazione.

Passaggio 4 Modifica hello/urls.py come segue:

from django.conf.urls import url


from django.contrib import admin
from hello import views

https://riptutorial.com/it/home 6
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', views.hello)
]

che collega la funzione view hello() a un URL.

Passaggio 5 Avviare il server.

python manage.py runserver

Passaggio 6

Passare a http://localhost:8000/ in un browser e vedrete:

Ciao mondo

Ambiente virtuale

Sebbene non sia strettamente necessario, si consiglia vivamente di avviare il progetto in un


"ambiente virtuale". Un ambiente virtuale è un contenitore (una directory) che contiene una
versione specifica di Python e un insieme di moduli (dipendenze), e che non interferisce con il
Python nativo del sistema operativo o altri progetti sullo stesso computer.

Impostando un ambiente virtuale diverso per ogni progetto su cui lavori, vari progetti di Django
possono essere eseguiti su diverse versioni di Python e possono mantenere i loro set di
dipendenze, senza il rischio di conflitti.

Python 3.3+
Python 3.3+ include già un modulo venv standard, che di solito si chiama pyvenv . In ambienti in cui
il comando pyvenv non è disponibile, è possibile accedere alla stessa funzionalità invocando
direttamente il modulo come python3 -m venv .

Per creare l'ambiente virtuale:

$ pyvenv <env-folder>
# Or, if pyvenv is not available
$ python3 -m venv <env-folder>

Python 2
Se si utilizza Python 2, è possibile prima installarlo come un modulo separato da pip:

$ pip install virtualenv

https://riptutorial.com/it/home 7
E quindi creare l'ambiente usando invece il comando virtualenv :

$ virtualenv <env-folder>

Attiva (qualsiasi versione)


L'ambiente virtuale è ora impostato. Per poterlo utilizzare, deve essere attivato nel terminale che
si desidera utilizzare.

Per 'attivare' l'ambiente virtuale (qualsiasi versione di Python)

Linux come:

$ source <env-folder>/bin/activate

Windows come:

<env-folder>\Scripts\activate.bat

Questo cambia la tua richiesta di indicare che l'ambiente virtuale è attivo. (<env-folder>) $

D'ora in poi, tutto ciò che verrà installato usando pip sarà installato nella tua cartella env virtuale,
non in tutto il sistema.

Per abbandonare l'ambiente virtuale usa deactivate :

(<env-folder>) $ deactivate

In alternativa: usa virtualenvwrapper


Potresti anche considerare l'utilizzo di virtualenvwrapper che rende molto utile la creazione e
l'attivazione di virtualenv e la separazione dal codice:

# Create a virtualenv
mkvirtualenv my_virtualenv

# Activate a virtualenv
workon my_virtualenv

# Deactivate the current virtualenv


deactivate

In alternativa: usa pyenv + pyenv-viritualenv


Negli ambienti in cui è necessario gestire più versioni Python, è possibile trarre vantaggio da

https://riptutorial.com/it/home 8
virtualenv con pyenv-virtualenv:

# Create a virtualenv for specific Python version


pyenv virtualenv 2.7.10 my-virtual-env-2.7.10

# Create a vritualenv for active python verion


pyenv virtualenv venv34

# Activate, deactivate virtualenv


pyenv activate <name>
pyenv deactivate

Quando si usano virtualenvs, è spesso utile impostare PYTHONPATH e DJANGO_SETTINGS_MODULE nello


script postactivate .

#!/bin/sh
# This hook is sourced after this virtualenv is activated

# Set PYTHONPATH to isolate the virtualenv so that only modules installed


# in the virtualenv are available
export PYTHONPATH="/home/me/path/to/your/project_root:$VIRTUAL_ENV/lib/python3.4"

# Set DJANGO_SETTINGS_MODULE if you don't use the default `myproject.settings`


# or if you use `django-admin` rather than `manage.py`
export DJANGO_SETTINGS_MODULE="myproject.settings.dev"

Imposta il tuo percorso del progetto


Spesso è anche utile impostare il percorso del progetto all'interno di uno speciale file .project che
si trova nella tua base <env-folder> . Quando lo fai, ogni volta che attivi il tuo ambiente virtuale,
cambierà la directory attiva nel percorso specificato.

Crea un nuovo file chiamato <env-folder>/.project . Il contenuto del file dovrebbe essere SOLO il
percorso della directory del progetto.

/path/to/project/directory

Ora avvia il tuo ambiente virtuale (usando source <env-folder>/bin/activate o workon my_virtualenv
) e il tuo terminale cambierà directory in /path/to/project/directory .

Esempio di file singolo Hello World

Questo esempio mostra un modo minimo per creare una pagina Hello World in Django. Questo ti
aiuterà a capire che il comando di django-admin startproject example crea fondamentalmente un
sacco di cartelle e file e che non hai necessariamente bisogno di quella struttura per eseguire il
tuo progetto.

1. Crea un file chiamato file.py

2. Copia e incolla il seguente codice in quel file.

https://riptutorial.com/it/home 9
import sys

from django.conf import settings

settings.configure(
DEBUG=True,
SECRET_KEY='thisisthesecretkey',
ROOT_URLCONF=__name__,
MIDDLEWARE_CLASSES=(
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
),
)

from django.conf.urls import url


from django.http import HttpResponse

# Your code goes below this line.

def index(request):
return HttpResponse('Hello, World!')

urlpatterns = [
url(r'^$', index),
]

# Your code goes above this line

if __name__ == "__main__":
from django.core.management import execute_from_command_line

execute_from_command_line(sys.argv)

3. Vai al terminale ed esegui il file con questo comando python file.py runserver .

4. Apri il browser e vai su 127.0.0.1:8000 .

Progetto di facile impiego con supporto Docker.

Il modello di progetto Django di default va bene, ma una volta che hai implementato il tuo codice e
per esempio gli sviluppatori hanno messo le mani sul progetto, le cose si complicano. Quello che
puoi fare è separare il tuo codice sorgente dal resto che è necessario che sia nel tuo repository.

Puoi trovare un modello di progetto Django utilizzabile su GitHub .

Struttura del progetto


PROJECT_ROOT
├── devel.dockerfile
├── docker-compose.yml
├── nginx
│   └── project_name.conf
├── README.md
├── setup.py

https://riptutorial.com/it/home 10
└── src
├── manage.py
└── project_name
├── __init__.py
└── service
├── __init__.py
├── settings
│   ├── common.py
│   ├── development.py
│   ├── __init__.py
│   └── staging.py
├── urls.py
└── wsgi.py

Mi piace mantenere la directory dei service denominata service per ogni progetto grazie al fatto
che posso utilizzare lo stesso Dockerfile su tutti i miei progetti. La suddivisione dei requisiti e delle
impostazioni è già ben documentata qui:
Utilizzo di più file di requisiti
Utilizzando più impostazioni

Dockerfile
Partendo dal presupposto che solo gli sviluppatori fanno uso di Docker (non tutti gli sviluppatori si
fidano di questi tempi). Questo potrebbe essere un dev devel.dockerfile dell'ambiente di
devel.dockerfile :

FROM python:2.7
ENV PYTHONUNBUFFERED 1

RUN mkdir /run/service


ADD . /run/service
WORKDIR /run/service

RUN pip install -U pip


RUN pip install -I -e .[develop] --process-dependency-links

WORKDIR /run/service/src
ENTRYPOINT ["python", "manage.py"]
CMD ["runserver", "0.0.0.0:8000"]

L'aggiunta di soli requisiti consentirà di sfruttare la cache Docker durante la creazione: sarà
necessario ricostruire solo in base alla modifica dei requisiti.

Comporre
La composizione di Docker è utile, specialmente quando si dispone di più servizi per l'esecuzione
locale. docker-compose.yml :

version: '2'
services:

https://riptutorial.com/it/home 11
web:
build:
context: .
dockerfile: devel.dockerfile
volumes:
- "./src/{{ project_name }}:/run/service/src/{{ project_name }}"
- "./media:/run/service/media"
ports:
- "8000:8000"
depends_on:
- db
db:
image: mysql:5.6
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE={{ project_name }}
nginx:
image: nginx
ports:
- "80:80"
volumes:
- "./nginx:/etc/nginx/conf.d"
- "./media:/var/media"
depends_on:
- web

nginx
Il tuo ambiente di sviluppo dovrebbe essere il più vicino possibile all'ambiente prod, quindi mi
piace usare Nginx sin dall'inizio. Ecco un esempio di file di configurazione di nginx:

server {
listen 80;
client_max_body_size 4G;
keepalive_timeout 5;

location /media/ {
autoindex on;
alias /var/media/;
}

location / {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Ssl on;
proxy_connect_timeout 600;
proxy_read_timeout 600;
proxy_pass http://web:8000/;
}
}

https://riptutorial.com/it/home 12
uso
$ cd PROJECT_ROOT
$ docker-compose build web # build the image - first-time and after requirements change
$ docker-compose up # to run the project
$ docker-compose run --rm --service-ports --no-deps # to run the project - and be able to use
PDB
$ docker-compose run --rm --no-deps <management_command> # to use other than runserver
commands, like makemigrations
$ docker exec -ti web bash # For accessing django container shell, using it you will be
inside /run/service directory, where you can run ./manage shell, or other stuff
$ docker-compose start # Starting docker containers
$ docker-compose stop # Stopping docker containers

Leggi Iniziare con Django online: https://riptutorial.com/it/django/topic/200/iniziare-con-django

https://riptutorial.com/it/home 13
Capitolo 2: Aggregazioni di modelli
introduzione
Le aggregazioni sono metodi che consentono l'esecuzione di operazioni su (singoli e / o gruppi di)
righe di oggetti derivati da un modello.

Examples
Media, Minima, Massima, Somma da Queryset

class Product(models.Model):
name = models.CharField(max_length=20)
price = models.FloatField()

Per ottenere il prezzo medio di tutti i prodotti:

>>> from django.db.models import Avg, Max, Min, Sum


>>> Product.objects.all().aggregate(Avg('price'))
# {'price__avg': 124.0}

Per ottenere il prezzo minimo di tutti i prodotti:

>>> Product.objects.all().aggregate(Min('price'))
# {'price__min': 9}

Per ottenere il prezzo massimo di tutti i prodotti:

>>> Product.objects.all().aggregate(Max('price'))
# {'price__max':599 }

Per ottenere SUM dei prezzi di tutti i prodotti:

>>> Product.objects.all().aggregate(Sum('price'))
# {'price__sum':92456 }

Conta il numero di relazioni estere

class Category(models.Model):
name = models.CharField(max_length=20)

class Product(models.Model):
name = models.CharField(max_length=64)
category = models.ForeignKey(Category, on_delete=models.PROTECT)

Per ottenere il numero di prodotti per ogni categoria:

https://riptutorial.com/it/home 14
>>> categories = Category.objects.annotate(Count('product'))

Aggiunge l'attributo <field_name>__count a ogni istanza restituita:

>>> categories.values_list('name', 'product__count')


[('Clothing', 42), ('Footwear', 12), ...]

Puoi fornire un nome personalizzato per il tuo attributo utilizzando un argomento di parole chiave:

>>> categories = Category.objects.annotate(num_products=Count('product'))

Puoi utilizzare il campo annotato in querysets:

>>> categories.order_by('num_products')
[<Category: Footwear>, <Category: Clothing>]

>>> categories.filter(num_products__gt=20)
[<Category: Clothing>]

GROUB PER ... COUNT / SUM Equivalente di Django ORM

Siamo in grado di eseguire un GROUP BY ... COUNT o un GROUP BY ... SUM query SQL equivalenti sui
Django ORM, con l'uso di annotate() , values() , order_by() e le django.db.models s' Count e Sum
metodi rispettosamente:

Lascia che il nostro modello sia:

class Books(models.Model):
title = models.CharField()
author = models.CharField()
price = models.FloatField()

GROUP BY ... COUNT :

• Supponiamo che vogliamo contare quanti oggetti libro per autore distinto esistono nella
nostra tabella Books :

result = Books.objects.values('author')
.order_by('author')
.annotate(count=Count('author'))

• Ora il result contiene un set di query con due colonne: author e count :

author | count
------------|-------
OneAuthor | 5
OtherAuthor | 2
... | ...

https://riptutorial.com/it/home 15
GROUB BY ... SUM :

• Supponiamo che vogliamo sommare il prezzo di tutti i libri per autore distinto presenti nella
nostra tabella Books :

result = Books.objects.values('author')
.order_by('author')
.annotate(total_price=Sum('price'))

• Ora il result contiene un set di query con due colonne: author e total_price :

author | total_price
------------|-------------
OneAuthor | 100.35
OtherAuthor | 50.00
... | ...

Leggi Aggregazioni di modelli online: https://riptutorial.com/it/django/topic/3775/aggregazioni-di-


modelli

https://riptutorial.com/it/home 16
Capitolo 3: Amministrazione
Examples
Cambia lista

Supponiamo tu abbia una semplice app myblog con il seguente modello:

from django.conf import settings


from django.utils import timezone

class Article(models.Model):
title = models.CharField(max_length=70)
slug = models.SlugField(max_length=70, unique=True)
author = models.ForeignKey(settings.AUTH_USER_MODEL, models.PROTECT)
date_published = models.DateTimeField(default=timezone.now)
is_draft = models.BooleanField(default=True)
content = models.TextField()

La "lista dei cambiamenti" di Django Admin è la pagina che elenca tutti gli oggetti di un dato
modello.

from django.contrib import admin


from myblog.models import Article

@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
pass

Di default, userà il __str__() (o __unicode__() se tu su python2) del tuo modello per visualizzare il
"nome" dell'oggetto. Ciò significa che se non l'hai sovrascritto, vedrai un elenco di articoli, tutti
denominati "Articolo oggetto". Per modificare questo comportamento, puoi impostare il __str__() :

class Article(models.Model):
def __str__(self):
return self.title

Ora, tutti i tuoi articoli dovrebbero avere un nome diverso e più esplicito di "Articolo oggetto".

Tuttavia potresti voler visualizzare altri dati in questo elenco. Per questo, usa list_display :

@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['__str__', 'author', 'date_published', 'is_draft']

list_display non è limitato ai campi e alle proprietà del modello. può anche essere un metodo di
ModelAdmin :

from django.forms.utils import flatatt

https://riptutorial.com/it/home 17
from django.urls import reverse
from django.utils.html import format_html

@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'author_link', 'date_published', 'is_draft']

def author_link(self, obj):


author = obj.author
opts = author._meta
route = '{}_{}_change'.format(opts.app_label, opts.model_name)
author_edit_url = reverse(route, args=[author.pk])
return format_html(
'<a{}>{}</a>', flatatt({'href': author_edit_url}), author.first_name)

# Set the column name in the change list


author_link.short_description = "Author"
# Set the field to use when ordering using this column
author_link.admin_order_field = 'author__firstname'

Ulteriori stili CSS e script JS per la pagina di amministrazione

Supponiamo di avere un semplice modello Customer :

class Customer(models.Model):
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
is_premium = models.BooleanField(default=False)

Si registra in admin Django e aggiungere campo di ricerca per first_name e last_name :

@admin.register(Customer)
class CustomerAdmin(admin.ModelAdmin):
list_display = ['first_name', 'last_name', 'is_premium']
search_fields = ['first_name', 'last_name']

Dopo aver effettuato questa operazione, i campi di ricerca vengono visualizzati nella pagina
dell'elenco di amministratori con il segnaposto predefinito: " parola chiave ". Ma cosa succede se
si desidera modificare quel segnaposto su " Cerca per nome "?

Puoi farlo passando il file Javascript personalizzato in admin Media :

@admin.register(Customer)
class CustomerAdmin(admin.ModelAdmin):
list_display = ['first_name', 'last_name', 'is_premium']
search_fields = ['first_name', 'last_name']

class Media:
#this path may be any you want,
#just put it in your static folder
js = ('js/admin/placeholder.js', )

Puoi utilizzare la barra degli strumenti debug del browser per trovare l'ID o la classe Django
impostati su questa barra di ricerca e quindi scrivere il tuo codice js:

https://riptutorial.com/it/home 18
$(function () {
$('#searchbar').attr('placeholder', 'Search by name')
})

Anche la classe Media ti consente di aggiungere file css con l'oggetto dizionario:

class Media:
css = {
'all': ('css/admin/styles.css',)
}

Ad esempio, è necessario visualizzare ogni elemento della colonna first_name in un colore


specifico.
Per impostazione predefinita Django crea una colonna di tabella per ogni elemento in list_display
, tutti i tag <td> avranno classe css come field-'list_display_name' , nel nostro caso sarà
field_first_name

.field_first_name {
background-color: #e6f2ff;
}

Se vuoi personalizzare altri comportamenti aggiungendo JS o alcuni stili css, puoi sempre
controllare id e classi di elementi nello strumento di debug del browser.

Gestione di chiavi esterne che fanno riferimento a tabelle di grandi dimensioni

Per impostazione predefinita, Django ForeignKey rendering ForeignKey campi ForeignKey come input
<select> . Ciò può causare il caricamento molto lento delle pagine se nella tabella di riferimento
sono presenti migliaia o decine di migliaia di voci. E anche se hai solo centinaia di voci, è
abbastanza scomodo cercare una voce particolare tra tutte.

Un modulo esterno molto utile per questo è django-autocomplete-light (DAL). Ciò consente di
utilizzare i campi di completamento automatico invece dei campi <select> .

https://riptutorial.com/it/home 19
views.py

from dal import autocomplete

class CityAutocomp(autocomplete.Select2QuerySetView):
def get_queryset(self):
qs = City.objects.all()
if self.q:
qs = qs.filter(name__istartswith=self.q)
return qs

urls.py

urlpatterns = [
url(r'^city-autocomp/$', CityAutocomp.as_view(), name='city-autocomp'),
]

forms.py

from dal import autocomplete

class PlaceForm(forms.ModelForm):
city = forms.ModelChoiceField(
queryset=City.objects.all(),
widget=autocomplete.ModelSelect2(url='city-autocomp')
)

class Meta:
model = Place

https://riptutorial.com/it/home 20
fields = ['__all__']

admin.py

@admin.register(Place)
class PlaceAdmin(admin.ModelAdmin):
form = PlaceForm

Leggi Amministrazione online: https://riptutorial.com/it/django/topic/1219/amministrazione

https://riptutorial.com/it/home 21
Capitolo 4: ArrayField - un campo specifico
PostgreSQL
Sintassi
• da django.contrib.postgres.fields importa ArrayField
• class ArrayField (base_field, size = None, ** opzioni)
• FooModel.objects.filter (array_field_name__contains = [oggetti, a, controllo])
• FooModel.objects.filter (array_field_name__contained_by = [oggetti, a, controllo])

Osservazioni
Nota che sebbene il parametro size sia passato a PostgreSQL, PostgreSQL non lo applicherà.

Quando si utilizza ArrayField si dovrebbe tenere a mente questa parola di avvertenza dalla
documentazione degli array Postgresql .

Suggerimento: gli array non sono insiemi; la ricerca di specifici elementi dell'array può
essere un segno di misdesign del database. Prendi in considerazione l'utilizzo di una
tabella separata con una riga per ogni elemento che sarebbe un elemento dell'array.
Questo sarà più facile da cercare, ed è probabile che scala in modo migliore per un
gran numero di elementi.

Examples
Un ArrayField di base

Per creare un ArrayField PostgreSQL, dovremmo dare a ArrayField il tipo di dati che vogliamo
archiviare come campo come primo argomento. Poiché archiviamo le valutazioni dei libri,
utilizzeremo FloatField .

from django.db import models, FloatField


from django.contrib.postgres.fields import ArrayField

class Book(models.Model):
ratings = ArrayField(FloatField())

Specifica della dimensione massima di un ArrayField

from django.db import models, IntegerField


from django.contrib.postgres.fields import ArrayField

class IceCream(models.Model):
scoops = ArrayField(IntegerField() # we'll use numbers to ID the scoops
, size=6) # our parlor only lets you have 6 scoops

https://riptutorial.com/it/home 22
Quando si utilizza il parametro size, viene passato a postgresql, che lo accetta e quindi lo ignora!
Quindi è abbastanza possibile aggiungere 7 interi al campo scoops sopra usando la console
postgresql.

Interrogare per l'appartenenza a ArrayField con contiene

Questa query restituisce tutti i coni con una pallina di cioccolato e uno scoop alla vaniglia.

VANILLA, CHOCOLATE, MINT, STRAWBERRY = 1, 2, 3, 4 # constants for flavors


choco_vanilla_cones = IceCream.objects.filter(scoops__contains=[CHOCOLATE, VANILLA])

Non dimenticare di importare il modello IceCream dal tuo file models.py .

Ricorda inoltre che django non creerà un indice per ArrayField . Se stai andando a cercarli, avrai
bisogno di un indice e dovrà essere creato manualmente con una chiamata a RunSQL nel tuo file
di migrazione.

Nesting ArrayFields

È possibile nidificare ArrayField passando un altro ArrayField dato che è base_field .

from django.db import models, IntegerField


from django.contrib.postgres.fields import ArrayField

class SudokuBoard(models.Model):
numbers = ArrayField(
ArrayField(
models.IntegerField(),
size=9,
),
size=9,
)

Interrogazione per tutti i modelli che contengono elementi in un elenco con


contained_by

Questa query restituisce tutti i coni con uno scoop alla menta o uno scoop alla vaniglia.

minty_vanilla_cones = IceCream.objects.filter(scoops__contained_by=[MINT, VANILLA])

Leggi ArrayField - un campo specifico PostgreSQL online:


https://riptutorial.com/it/django/topic/1693/arrayfield---un-campo-specifico-postgresql

https://riptutorial.com/it/home 23
Capitolo 5: Associazione di stringhe alle
stringhe con HStoreField: un campo
specifico PostgreSQL
Sintassi
• FooModel.objects.filter (field_name__key_name = 'valore da interrogare')

Examples
Impostazione di HStoreField

Innanzitutto, dovremo eseguire alcune impostazioni per far funzionare HStoreField .

1. assicurati che django.contrib.postgres sia nel tuo `INSTALLED_APPS


2. Aggiungi HStoreExtension alle tue migrazioni. Ricordarsi di inserire HStoreExtension prima di
qualsiasi migrazione di CreateModel o AddField .

from django.contrib.postgres.operations import HStoreExtension


from django.db import migrations

class FooMigration(migrations.Migration):
# put your other migration stuff here
operations = [
HStoreExtension(),
...
]

Aggiunta di HStoreField al modello

-> Nota: assicurati di configurare HStoreField prima di continuare con questo esempio.
(sopra)

Non sono richiesti parametri per inizializzare un HStoreField .

from django.contrib.postgres.fields import HStoreField


from django.db import models

class Catalog(models.model):
name = models.CharField(max_length=200)
titles_to_authors = HStoreField()

Creazione di una nuova istanza di modello

Passa un dizionario Python nativo che associa stringhe a stringhe per create() .

https://riptutorial.com/it/home 24
Catalog.objects.create(name='Library of Congress', titles_to_authors={
'Using HStoreField with Django': 'CrazyPython and la communidad',
'Flabbergeists and thingamajigs': 'La Artista Fooista',
'Pro Git': 'Scott Chacon and Ben Straub',
})

Esecuzione di ricerche chiave

Catalog.objects.filter(titles__Pro_Git='Scott Chacon and Ben Straub')

L'utilizzo contiene

Passa un oggetto dict a field_name__contains come argomento della parola chiave.

Catalog.objects.filter(titles__contains={
'Pro Git': 'Scott Chacon and Ben Straub'})

Equivale all'operatore SQL `@>`.

Leggi Associazione di stringhe alle stringhe con HStoreField: un campo specifico PostgreSQL
online: https://riptutorial.com/it/django/topic/2670/associazione-di-stringhe-alle-stringhe-con-
hstorefield--un-campo-specifico-postgresql

https://riptutorial.com/it/home 25
Capitolo 6: Attività asincrone (sedano)
Osservazioni
Celery è una coda di attività che può eseguire lavori in background o pianificati e si integra
abbastanza bene con Django. Celery richiede qualcosa di conosciuto come broker dei messaggi
per passare i messaggi dall'invocazione ai lavoratori. Questo broker di messaggi può essere redis,
rabbitmq o anche Django ORM / db anche se questo non è un approccio raccomandato.

Prima di iniziare con l'esempio, dovrai configurare il sedano. Per configurare il sedano, creare un
file celery_config.py nell'app principale, parallelamente al file settings.py .

from __future__ import absolute_import


import os
from celery import Celery
from django.conf import settings

# broker url
BROKER_URL = 'redis://localhost:6379/0'

# Indicate Celery to use the default Django settings module


os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')

app = Celery('config')
app.config_from_object('django.conf:settings')
# if you do not need to keep track of results, this can be turned off
app.conf.update(
CELERY_RESULT_BACKEND=BROKER_URL,
)

# This line will tell Celery to autodiscover all your tasks.py that are in your app folders
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)

E nel file __init__.py dell'app principale, importa l'app di sedano. come questo

# -*- coding: utf-8 -*-


# Not required for Python 3.
from __future__ import absolute_import

from .celery_config import app as celery_app # noqa

Per eseguire il gestore di sedici, utilizzare questo comando al livello in cui è manage.py.

# pros is your django project,


celery -A proj worker -l info

Examples
Semplice esempio per aggiungere 2 numeri

https://riptutorial.com/it/home 26
Per iniziare:

1. Installa sedano per pip install celery


2. configurare il sedano (vai alla sezione commenti)

from __future__ import absolute_import, unicode_literals

from celery.decorators import task

@task
def add_number(x, y):
return x + y

È possibile eseguire questo in modo asincrono utilizzando il metodo .delay() .

add_number.delay(5, 10) , dove 5 e 10 sono gli argomenti per la funzione add_number

Per verificare se la funzione asincrona ha terminato l'operazione, è possibile utilizzare la funzione


.ready() sull'oggetto async restituito dal metodo delay .

Per recuperare il risultato del calcolo, è possibile utilizzare l'attributo .result sull'oggetto async.

Esempio

async_result_object = add_number.delay(5, 10)


if async_result_object.ready():
print(async_result_object.result)

Leggi Attività asincrone (sedano) online: https://riptutorial.com/it/django/topic/5481/attivita-


asincrone--sedano-

https://riptutorial.com/it/home 27
Capitolo 7: Backend di autenticazione
Examples
Email di back-end di autenticazione

L'autenticazione predefinita di Django funziona su campi username e password . Il back-end di


autenticazione e-mail autenticherà gli utenti in base a e email e password .

from django.contrib.auth import get_user_model

class EmailBackend(object):
"""
Custom Email Backend to perform authentication via email
"""
def authenticate(self, username=None, password=None):
user_model = get_user_model()
try:
user = user_model.objects.get(email=username)
if user.check_password(password): # check valid password
return user # return user to be authenticated
except user_model.DoesNotExist: # no matching user exists
return None

def get_user(self, user_id):


user_model = get_user_model()
try:
return user_model.objects.get(pk=user_id)
except user_model.DoesNotExist:
return None

Aggiungi questo back-end di autenticazione all'impostazione AUTHENTICATION_BACKENDS .

# settings.py
AUTHENTICATION_BACKENDS = (
'my_app.backends.EmailBackend',
...
)

Leggi Backend di autenticazione online: https://riptutorial.com/it/django/topic/1282/backend-di-


autenticazione

https://riptutorial.com/it/home 28
Capitolo 8: Comandi di gestione
introduzione
I comandi di gestione sono script potenti e flessibili che possono eseguire azioni sul progetto
Django o sul database sottostante. Oltre ai vari comandi predefiniti, è possibile scrivere i propri!

Rispetto ai normali script Python, l'utilizzo del framework dei comandi di gestione significa che
alcune noiose operazioni di configurazione vengono eseguite automaticamente dietro le quinte.

Osservazioni
I comandi di gestione possono essere chiamati da:

• django-admin <command> [options]


• python -m django <command> [options]
• python manage.py <command> [options]
• ./manage.py <command> [options] se manage.py ha permessi di esecuzione ( chmod +x
manage.py )

Per usare i comandi di gestione con Cron:

*/10 * * * * pythonuser /var/www/dev/env/bin/python /var/www/dev/manage.py <command> [options]


> /dev/null

Examples
Creazione ed esecuzione di un comando di gestione

Per eseguire azioni in Django utilizzando la riga di comando o altri servizi (in cui l'utente / richiesta
non viene utilizzato), è possibile utilizzare i management commands .

I moduli Django possono essere importati secondo necessità.

Per ogni comando è necessario creare un file separato: myapp/management/commands/my_command.py


(Le directory di management e commands devono avere un file __init__.py vuoto)

from django.core.management.base import BaseCommand, CommandError

# import additional classes/modules as needed


# from myapp.models import Book

class Command(BaseCommand):
help = 'My custom django management command'

def add_arguments(self, parser):


parser.add_argument('book_id', nargs='+', type=int)
parser.add_argument('author' , nargs='+', type=str)

https://riptutorial.com/it/home 29
def handle(self, *args, **options):
bookid = options['book_id']
author = options['author']
# Your code goes here

# For example:
# books = Book.objects.filter(author="bob")
# for book in books:
# book.name = "Bob"
# book.save()

Qui il nome della classe Command è obbligatorio che estende BaseCommand o una delle sue
sottoclassi.

Il nome del comando di gestione è il nome del file che lo contiene. Per eseguire il comando
nell'esempio precedente, utilizzare quanto segue nella directory del progetto:

python manage.py my_command

Si noti che l'avvio di un comando può richiedere alcuni secondi (a causa


dell'importazione dei moduli). Quindi in alcuni casi si consiglia di creare processi daemon
invece di management commands di management commands .

Maggiori informazioni sui comandi di gestione

Ottieni l'elenco dei comandi esistenti

È possibile ottenere l'elenco dei comandi disponibili seguendo la seguente procedura:

>>> python manage.py help

Se non capisci alcun comando o cerchi argomenti opzionali, puoi usare l'argomento -h come
questo

>>> python manage.py command_name -h

Qui command_name sarà il tuo nome comando desiderato, questo ti mostrerà il testo di aiuto dal
comando.

>>> python manage.py runserver -h


>>> usage: manage.py runserver [-h] [--version] [-v {0,1,2,3}]
[--settings SETTINGS] [--pythonpath PYTHONPATH]
[--traceback] [--no-color] [--ipv6] [--nothreading]
[--noreload] [--nostatic] [--insecure]
[addrport]

Starts a lightweight Web server for development and also serves static files.

positional arguments:
addrport Optional port number, or ipaddr:port

https://riptutorial.com/it/home 30
optional arguments:
-h, --help show this help message and exit
--version show program's version number and exit
-v {0,1,2,3}, --verbosity {0,1,2,3}
Verbosity level; 0=minimal output, 1=normal output,
2=verbose output, 3=very verbose output
--settings SETTINGS The Python path to a settings module, e.g.
"myproject.settings.main". If this isn't provided, the
DJANGO_SETTINGS_MODULE environment variable will be
used.
--pythonpath PYTHONPATH
A directory to add to the Python path, e.g.
"/home/djangoprojects/myproject".
--traceback Raise on CommandError exceptions
--no-color Don't colorize the command output.
--ipv6, -6 Tells Django to use an IPv6 address.
--nothreading Tells Django to NOT use threading.
--noreload Tells Django to NOT use the auto-reloader.
--nostatic Tells Django to NOT automatically serve static files
at STATIC_URL.
--insecure Allows serving static files even if DEBUG is False.

Elenco dei comandi disponibili

Utilizzando django-admin invece di manage.py

Puoi sbarazzarti di manage.py e usare invece il comando django-admin . Per fare ciò, dovrai fare
manualmente ciò che manage.py fa:

• Aggiungi il tuo percorso di progetto al tuo PYTHONPATH


• Imposta il DJANGO_SETTINGS_MODULE

export PYTHONPATH="/home/me/path/to/your_project"
export DJANGO_SETTINGS_MODULE="your_project.settings"

Ciò è particolarmente utile in una virtualizzazione in cui è possibile impostare queste variabili di
ambiente nello script postactivate .

django-admin comando django-admin ha il vantaggio di essere disponibile ovunque tu sia sul tuo
filesystem.

Comandi di gestione incorporati

Django viene fornito con una serie di comandi di gestione incorporati, usando python manage.py
[command] o, quando manage.py ha diritti + x (eseguibili) semplicemente ./manage.py [command] . I
seguenti sono alcuni dei più usati:

Ottieni un elenco di tutti i comandi disponibili

./manage.py help

Esegui il tuo server Django su localhost: 8000; essenziale per i test locali

https://riptutorial.com/it/home 31
./manage.py runserver

Esegui una console python (o ipython se installata) con le impostazioni Django del tuo progetto
precaricato (il tentativo di accedere a parti del tuo progetto in un terminale python senza farlo
fallirebbe).

./manage.py shell

Crea un nuovo file di migrazione del database in base alle modifiche apportate ai tuoi modelli.
Vedi Migrazioni

./manage.py makemigrations

Applicare eventuali migrazioni non applicate al database corrente.

./manage.py migrate

Esegui la suite di test del tuo progetto. Vedi Test unitario

./manage.py test

Prendere tutti i file statici del progetto e inserirli nella cartella specificata in STATIC_ROOT modo che
possano essere pubblicati in produzione.

./manage.py collectstatic

Permette di creare superutente.

./manage.py createsuperuser

Cambia la password di un utente specificato.

./manage.py changepassword username

Elenco completo dei comandi disponibili

Leggi Comandi di gestione online: https://riptutorial.com/it/django/topic/1661/comandi-di-gestione

https://riptutorial.com/it/home 32
Capitolo 9: Come resettare le migrazioni di
django
introduzione
Man mano che sviluppi un'app di Django, ci potrebbero essere situazioni in cui puoi risparmiare
molto tempo semplicemente ripulendo e reimpostando le tue migrazioni.

Examples
Reimpostazione della migrazione di Django: eliminazione del database
esistente e migrazione come nuova

Cancella / cancella il tuo database Se stai usando SQLite per il tuo database, cancella questo file.
Se si utilizza MySQL / Postgres o qualsiasi altro sistema di database, sarà necessario rilasciare il
database e ricreare un nuovo database.

Ora dovrai eliminare tutti i file di migrazione tranne il file "init.py" che si trova nella cartella delle
migrazioni nella cartella dell'app.

Di solito la cartella delle migrazioni si trova in

/your_django_project/your_app/migrations

Ora che hai eliminato il database e il file di migrazione, esegui i seguenti comandi come faresti
con la migrazione la prima volta che avvii il progetto django.

python manage.py makemigrations


python manage.py migrate

Leggi Come resettare le migrazioni di django online:


https://riptutorial.com/it/django/topic/9513/come-resettare-le-migrazioni-di-django

https://riptutorial.com/it/home 33
Capitolo 10: Come usare Django con
Cookiecutter?
Examples
Installazione e configurazione del progetto django con Cookiecutter

Di seguito sono riportati i prerequisiti per l'installazione di Cookiecutter:

• seme
• virtualenv
• PostgreSQL

Crea un virtualenv per il tuo progetto e attivalo:

$ mkvirtualenv <virtualenv name>


$ workon <virtualenv name>

Ora installa Cookiecutter usando:

$ pip install cookiecutter

Cambia directory nella cartella in cui desideri che il tuo progetto vivi. Ora esegui il seguente
comando per generare un progetto django:

$ cookiecutter https://github.com/pydanny/cookiecutter-django.git

Questo comando esegue cookiecutter con il repo cookiecutter-django, chiedendoci di inserire


dettagli specifici del progetto. Premi "invio" senza digitare nulla per utilizzare i valori predefiniti,
che sono mostrati in [parentesi] dopo la domanda.

project_name [project_name]: example_project


repo_name [example_project]:
author_name [Your Name]: Atul Mishra
email [Your email]: [email protected]
description [A short description of the project.]: Demo Project
domain_name [example.com]: example.com
version [0.1.0]: 0.1.0
timezone [UTC]: UTC
now [2016/03/08]: 2016/03/08
year [2016]: 2016
use_whitenoise [y]: y
use_celery [n]: n
use_mailhog [n]: n
use_sentry [n]: n
use_newrelic [n]: n
use_opbeat [n]: n
windows [n]: n

https://riptutorial.com/it/home 34
use_python2 [n]: n

Maggiori dettagli sulle opzioni di generazione del progetto sono disponibili nella documentazione
ufficiale. Il progetto è ora configurato.

Leggi Come usare Django con Cookiecutter? online:


https://riptutorial.com/it/django/topic/5385/come-usare-django-con-cookiecutter-

https://riptutorial.com/it/home 35
Capitolo 11: Configurazione del database
Examples
MySQL / MariaDB

Django supporta MySQL 5.5 e versioni successive.

Assicurati di avere alcuni pacchetti installati:

$ sudo apt-get install mysql-server libmysqlclient-dev


$ sudo apt-get install python-dev python-pip # for python 2
$ sudo apt-get install python3-dev python3-pip # for python 3

Oltre a uno dei driver MySQL di Python ( mysqlclient la scelta consigliata per Django):

$ pip install mysqlclient # python 2 and 3


$ pip install MySQL-python # python 2
$ pip install pymysql # python 2 and 3

La codifica del database non può essere impostata da Django, ma deve essere
configurata a livello di database. Cerca default-character-set in my.cnf (o
/etc/mysql/mariadb.conf/*.cnf ) e imposta la codifica:

[mysql]
#default-character-set = latin1 #default on some systems.
#default-character-set = utf8mb4 #default on some systems.
default-character-set = utf8

...
[mysqld]
#character-set-server = utf8mb4
#collation-server = utf8mb4_general_ci
character-set-server = utf8
collation-server = utf8_general_ci

Configurazione del database per MySQL o MariaDB

#myapp/settings/settings.py

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'DB_NAME',
'USER': 'DB_USER',
'PASSWORD': 'DB_PASSWORD',
'HOST': 'localhost', # Or an IP Address that your database is hosted on
'PORT': '3306',
#optional:
'OPTIONS': {
'charset' : 'utf8',

https://riptutorial.com/it/home 36
'use_unicode' : True,
'init_command': 'SET '
'storage_engine=INNODB,'
'character_set_connection=utf8,'
'collation_connection=utf8_bin'
#'sql_mode=STRICT_TRANS_TABLES,' # see note below
#'SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED',
},
'TEST_CHARSET': 'utf8',
'TEST_COLLATION': 'utf8_general_ci',
}
}

Se si utilizza il connettore MySQL di Oracle, la linea ENGINE dovrebbe avere il seguente aspetto:

'ENGINE': 'mysql.connector.django',

Quando crei un database, assicurati di specificare la codifica e le regole di confronto:

CREATE DATABASE mydatabase CHARACTER SET utf8 COLLATE utf8_bin

Da MySQL 5.7 in poi e su nuove installazioni di MySQL 5.6, il valore predefinito


dell'opzione sql_mode contiene STRICT_TRANS_TABLES . Quell'opzione degrada gli
avvisi in errori quando i dati vengono troncati al momento dell'inserimento. Django
consiglia vivamente di attivare una modalità rigorosa per MySQL per prevenire la
perdita di dati (STRICT_TRANS_TABLES o STRICT_ALL_TABLES). Per abilitare
aggiungi a /etc/my.cnf sql-mode = STRICT_TRANS_TABLES

PostgreSQL

Assicurati di avere alcuni pacchetti installati:

sudo apt-get install libpq-dev


pip install psycopg2

Impostazioni del database per PostgreSQL:

#myapp/settings/settings.py

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'myprojectDB',
'USER': 'myprojectuser',
'PASSWORD': 'password',
'HOST': '127.0.0.1',
'PORT': '5432',
}
}

Nelle versioni precedenti puoi anche usare l'alias django.db.backends.postgresql_psycopg2 .

https://riptutorial.com/it/home 37
Usando Postresql avrai accesso ad alcune funzionalità extra:

Modelfields:

ArrayField # A field for storing lists of data.


HStoreField # A field for storing mappings of strings to strings.
JSONField # A field for storing JSON encoded data.
IntegerRangeField # Stores a range of integers
BigIntegerRangeField # Stores a big range of integers
FloatRangeField # Stores a range of floating point values.
DateTimeRangeField # Stores a range of timestamps

sqlite

sqlite è l'impostazione predefinita per Django. Non dovrebbe essere usato in produzione poiché è
solitamente lento.

#myapp/settings/settings.py

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'db/development.sqlite3',
'USER': '',
'PASSWORD': '',
'HOST': '',
'PORT': '',
},
}

infissi

Le fixture sono dati iniziali per il database. Il modo più semplice quando si hanno già alcuni dati
esistenti è usare il comando dumpdata

./manage.py dumpdata > databasedump.json # full database


./manage.py dumpdata myapp > databasedump.json # only 1 app
./manage.py dumpdata myapp.mymodel > databasedump.json # only 1 model (table)

Questo creerà un file json che può essere importato di nuovo usando

./manage.py loaddata databasedump.json

Quando si utilizza loadddata senza specificare un file, Django cercherà una cartella fixtures nella
propria app o l'elenco delle directory fornite in FIXTURE_DIRS nelle impostazioni e utilizzerà invece il
suo contenuto.

/myapp
/fixtures
myfixtures.json
morefixtures.xml

https://riptutorial.com/it/home 38
I possibili formati di file sono: JSON, XML or YAML

Esempio JSON di Fixtures:

[
{
"model": "myapp.person",
"pk": 1,
"fields": {
"first_name": "John",
"last_name": "Lennon"
}
},
{
"model": "myapp.person",
"pk": 2,
"fields": {
"first_name": "Paul",
"last_name": "McCartney"
}
}
]

Esempio di YAML delle fixture:

- model: myapp.person
pk: 1
fields:
first_name: John
last_name: Lennon
- model: myapp.person
pk: 2
fields:
first_name: Paul
last_name: McCartney

Esempio XML Fixtures:

<?xml version="1.0" encoding="utf-8"?>


<django-objects version="1.0">
<object pk="1" model="myapp.person">
<field type="CharField" name="first_name">John</field>
<field type="CharField" name="last_name">Lennon</field>
</object>
<object pk="2" model="myapp.person">
<field type="CharField" name="first_name">Paul</field>
<field type="CharField" name="last_name">McCartney</field>
</object>
</django-objects>

Django Cassandra Engine

• Installa pip: $ pip install django-cassandra-engine


• Aggiungi Introduzione a INSTALLED_APPS nel tuo file settings.py: INSTALLED_APPS =
['django_cassandra_engine']
• Impostazione Cange DATABASES Standart:

https://riptutorial.com/it/home 39
Standart

DATABASES = {
'default': {
'ENGINE': 'django_cassandra_engine',
'NAME': 'db',
'TEST_NAME': 'test_db',
'HOST': 'db1.example.com,db2.example.com',
'OPTIONS': {
'replication': {
'strategy_class': 'SimpleStrategy',
'replication_factor': 1
}
}
}
}

Cassandra crea un nuovo utente cqlsh:

DATABASES = {
'default': {
'ENGINE': 'django_cassandra_engine',
'NAME': 'db',
'TEST_NAME': 'test_db',
'USER_NAME'='cassandradb',
'PASSWORD'= '123cassandra',
'HOST': 'db1.example.com,db2.example.com',
'OPTIONS': {
'replication': {
'strategy_class': 'SimpleStrategy',
'replication_factor': 1
}
}
}

Leggi Configurazione del database online:


https://riptutorial.com/it/django/topic/4933/configurazione-del-database

https://riptutorial.com/it/home 40
Capitolo 12: CRUD in Django
Examples
** Esempio CRUD più semplice **

Se ritieni che questi passaggi non siano familiari, considera di iniziare da qui . Nota che questi
passaggi provengono dalla documentazione di Overflow dello stack.

django-admin startproject myproject


cd myproject
python manage.py startapp myapp

myproject / settings.py Installa l'app

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myapp',
]

Crea un file chiamato urls.py nella directory myapp e lo aggiorna con la seguente vista.

from django.conf.urls import url


from myapp import views

urlpatterns = [
url(r'^$', views.index, name='index'),
]

Aggiorna l'altro file urls.py con il seguente contenuto.

from django.conf.urls import url


from django.contrib import admin
from django.conf.urls import include
from myapp import views

urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^myapp/', include('myapp.urls')),
url(r'^admin/', admin.site.urls),
]

Creare una cartella denominata templates all'interno della directory myapp . Quindi creare un file
denominato index.html all'interno della directory dei modelli . Completalo con il seguente
contenuto.

https://riptutorial.com/it/home 41
<!DOCTYPE html>
<html>
<head>
<title>myapp</title>
</head>
<body>
<h2>Simplest Crud Example</h2>
<p>This shows a list of names and lets you Create, Update and Delete them.</p>
<h3>Add a Name</h3>
<button>Create</button>
</body>
</html>

Abbiamo anche bisogno di una vista per mostrare index.html che possiamo creare modificando il
file views.py in questo modo:

from django.shortcuts import render, redirect

# Create your views here.


def index(request):
return render(request, 'index.html', {})

Ora hai la base su cui lavorerai. Il prossimo passo è creare un modello. Questo è l'esempio più
semplice possibile, quindi nella cartella models.py aggiungi il seguente codice.

from __future__ import unicode_literals

from django.db import models

# Create your models here.


class Name(models.Model):
name_value = models.CharField(max_length=100)

def __str__(self): # if Python 2 use __unicode__


return self.name_value

Questo crea un modello di un oggetto Nome che aggiungeremo al database con i seguenti
comandi dalla riga di comando.

python manage.py createsuperuser


python manage.py makemigrations
python manage.py migrate

Dovresti vedere alcune operazioni eseguite da Django. Questi configurano le tabelle e creano un
superutente che può accedere al database di amministrazione da una vista amministratore con
Django. A proposito, registriamo il nostro nuovo modello con la visualizzazione admin. Vai su
admin.py e aggiungi il seguente codice.

from django.contrib import admin


from myapp.models import Name
# Register your models here.

admin.site.register(Name)

https://riptutorial.com/it/home 42
Tornando alla riga di comando ora è possibile avviare il server con il comando python manage.py
runserver . Dovresti poter visitare http: // localhost: 8000 / e vedere la tua app. Passare quindi a
http: // localhost: 8000 / admin in modo da poter aggiungere un nome al progetto. Accedi e
aggiungi un Nome sotto la tabella MYAPP, l'abbiamo mantenuto semplice per l'esempio, quindi
assicurati che sia inferiore a 100 caratteri.

Per accedere al nome è necessario visualizzarlo da qualche parte. Modifica la funzione di indice
all'interno di views.py per estrarre tutti gli oggetti Nome dal database.

from django.shortcuts import render, redirect


from myapp.models import Name

# Create your views here.


def index(request):
names_from_db = Name.objects.all()
context_dict = {'names_from_context': names_from_db}
return render(request, 'index.html', context_dict)

Ora modifica il file index.html al seguente.

<!DOCTYPE html>
<html>
<head>
<title>myapp</title>
</head>
<body>
<h2>Simplest Crud Example</h2>
<p>This shows a list of names and lets you Create, Update and Delete them.</p>
{% if names_from_context %}
<ul>
{% for name in names_from_context %}
<li>{{ name.name_value }} <button>Delete</button>
<button>Update</button></li>
{% endfor %}
</ul>
{% else %}
<h3>Please go to the admin and add a Name under 'MYAPP'</h3>
{% endif %}
<h3>Add a Name</h3>
<button>Create</button>
</body>
</html>

Ciò dimostra la lettura in CRUD. All'interno della directory myapp creare un file forms.py. Aggiungi
il seguente codice:

from django import forms


from myapp.models import Name

class NameForm(forms.ModelForm):
name_value = forms.CharField(max_length=100, help_text = "Enter a name")

class Meta:
model = Name
fields = ('name_value',)

https://riptutorial.com/it/home 43
Aggiorna index.html nel modo seguente:

<!DOCTYPE html>
<html>
<head>
<title>myapp</title>
</head>
<body>
<h2>Simplest Crud Example</h2>
<p>This shows a list of names and lets you Create, Update and Delete them.</p>
{% if names_from_context %}
<ul>
{% for name in names_from_context %}
<li>{{ name.name_value }} <button>Delete</button>
<button>Update</button></li>
{% endfor %}
</ul>
{% else %}
<h3>Please go to the admin and add a Name under 'MYAPP'</h3>
{% endif %}
<h3>Add a Name</h3>
<form id="name_form" method="post" action="/">
{% csrf_token %}
{% for field in form.visible_fields %}
{{ field.errors }}
{{ field.help_text }}
{{ field }}
{% endfor %}
<input type="submit" name="submit" value="Create">
</form>
</body>
</html>

Successivamente aggiorna views.py nel modo seguente:

from django.shortcuts import render, redirect


from myapp.models import Name
from myapp.forms import NameForm

# Create your views here.


def index(request):
names_from_db = Name.objects.all()

form = NameForm()

context_dict = {'names_from_context': names_from_db, 'form': form}

if request.method == 'POST':
form = NameForm(request.POST)

if form.is_valid():
form.save(commit=True)
return render(request, 'index.html', context_dict)
else:
print(form.errors)

return render(request, 'index.html', context_dict)

Riavvia il tuo server e dovresti ora avere una versione funzionante dell'app con la C in create

https://riptutorial.com/it/home 44
completed.

TODO aggiunge aggiornamento ed elimina

Leggi CRUD in Django online: https://riptutorial.com/it/django/topic/7317/crud-in-django

https://riptutorial.com/it/home 45
Capitolo 13: Debug
Osservazioni
PDB

Pdb può anche stampare tutte le variabili esistenti in ambito globale o locale, digitando
rispettivamente globals() o locals() in (Pdb) prompt.

Examples
Utilizzo di Python Debugger (Pdb)

La maggior parte degli strumenti di debug di Django di base è pdb , una parte della libreria
standard di Python.

Script di visualizzazione iniziale

Esaminiamo un semplice script views.py :

from django.http import HttpResponse

def index(request):
foo = 1
bar = 0

bug = foo/bar

return HttpResponse("%d goes here." % bug)

Comando della console per eseguire il server:

python manage.py runserver

È ovvio che Django genererebbe un ZeroDivisionError quando ZeroDivisionError a caricare la


pagina indice, ma se fingiamo che il bug sia molto profondo nel codice, potrebbe diventare
davvero sgradevole.

Impostazione di un punto di interruzione

Fortunatamente, possiamo impostare un breakpoint per rintracciare quel bug:

from django.http import HttpResponse

# Pdb import
import pdb

https://riptutorial.com/it/home 46
def index(request):
foo = 1
bar = 0

# This is our new breakpoint


pdb.set_trace()

bug = foo/bar

return HttpResponse("%d goes here." % bug)

Comando della console per eseguire il server con pdb:

python -m pdb manage.py runserver

Ora sulla pagina il punto di interruzione del carico si attiverà (Pdb) nella shell, che bloccherà
anche il browser in sospeso.

Debugging con shell pdb

È tempo di eseguire il debug di questa vista interagendo con lo script tramite shell:

> ../views.py(12)index()
-> bug = foo/bar
# input 'foo/bar' expression to see division results:
(Pdb) foo/bar
*** ZeroDivisionError: division by zero
# input variables names to check their values:
(Pdb) foo
1
(Pdb) bar
0
# 'bar' is a source of the problem, so if we set it's value > 0...
(Pdb) bar = 1
(Pdb) foo/bar
1.0
# exception gone, ask pdb to continue execution by typing 'c':
(Pdb) c
[03/Aug/2016 10:50:45] "GET / HTTP/1.1" 200 111

Nell'ultima riga vediamo che la nostra vista ha restituito una risposta OK e l'esecuzione come
dovrebbe.

Per interrompere il ciclo pdb, basta inserire q in una shell.

Utilizzando la barra degli strumenti Debug di Django

Innanzitutto, è necessario installare django-debug-toolbar :

pip install django-debug-toolbar

settings.py :

https://riptutorial.com/it/home 47
Successivamente, includilo nelle app installate del progetto, ma fai attenzione: è sempre buona
norma utilizzare un diverso file settings.py per tali app e middleware di solo sviluppo come barra
degli strumenti di debug:

# If environment is dev...
DEBUG = True

INSTALLED_APPS += [
'debug_toolbar',
]

MIDDLEWARE += ['debug_toolbar.middleware.DebugToolbarMiddleware']

La barra degli strumenti di debug si basa anche su file statici, quindi dovrebbe essere inclusa
anche l'app appropriata:

INSTALLED_APPS = [
# ...
'django.contrib.staticfiles',
# ...
]

STATIC_URL = '/static/'

# If environment is dev...
DEBUG = True

INSTALLED_APPS += [
'debug_toolbar',
]

In alcuni casi, è anche necessario impostare INTERNAL_IPS in settings.py :

INTERNAL_IPS = ('127.0.0.1', )

urls.py :

In urls.py , come suggerisce la documentazione ufficiale, il successivo snippet dovrebbe abilitare


il routing della barra degli strumenti di debug:

if settings.DEBUG and 'debug_toolbar' in settings.INSTALLED_APPS:


import debug_toolbar
urlpatterns += [
url(r'^__debug__/', include(debug_toolbar.urls)),
]

Raccogli statico della barra degli strumenti dopo l'installazione:

python manage.py collectstatic

Ecco fatto, la barra degli strumenti di debug comparirà sulle pagine del tuo progetto, fornendo
varie informazioni utili sui tempi di esecuzione, SQL, file statici, segnali, ecc.

https://riptutorial.com/it/home 48
HTML:

Inoltre, django-debug-toolbar richiede un tipo di contenuto di tag text/html , <html> e <body> per
renderizzare correttamente.

Nel caso in cui sei sicuro di aver configurato tutto correttamente, ma la barra degli
strumenti di debug non viene ancora renderizzata: usa questa soluzione "nucleare" per
cercare di capirlo.

Usare "asserire False"

Durante lo sviluppo, inserisci la seguente riga nel tuo codice:

assert False, value

farà sì che django sollevi AssertionError con il valore fornito come messaggio di errore quando
viene eseguita questa riga.

Se questo si verifica in una vista, o in qualsiasi codice chiamato da una vista, e DEBUG=True è
impostato, nel browser verrà visualizzato uno stacktrace completo e dettagliato con molte
informazioni di debug.

Non dimenticare di rimuovere la linea quando hai finito!

Considera di scrivere più documenti, test, log e asserzioni invece di usare un


debugger

Il debug richiede tempo e fatica.

Invece di inseguire i bug con un debugger, considera di dedicare più tempo a migliorare il tuo
codice:

• Scrivi ed esegui i test . Python e Django dispongono di ottimi framework di test integrati,
che possono essere utilizzati per testare il codice molto più rapidamente rispetto a un
debugger manuale.
• Scrivere una documentazione adeguata per funzioni, classi e moduli. PEP 257 e Google's
Python Style Guide forniscono buone pratiche per la scrittura di buone docstring.
• Usa la registrazione per produrre l'output dal tuo programma - durante lo sviluppo e dopo la
distribuzione.
• Aggiungi assert ioni al tuo codice in posti importanti: riduce l'ambiguità, cattura i problemi
man mano che vengono creati.

Bonus: scrivi doctest per combinare documentazione e test!

Leggi Debug online: https://riptutorial.com/it/django/topic/5072/debug

https://riptutorial.com/it/home 49
Capitolo 14: Distribuzione
Examples
Esecuzione dell'applicazione Django con Gunicorn

1. Installa gunicorn

pip install gunicorn

2. Dalla cartella del progetto django (stessa cartella in cui si trova manage.py), eseguire il
comando seguente per eseguire il progetto django corrente con gunicorn

gunicorn [projectname].wsgi:application -b 127.0.0.1:[port number]

È possibile utilizzare l'opzione --env per impostare il percorso per caricare le impostazioni

gunicorn --env DJANGO_SETTINGS_MODULE=[projectname].settings [projectname].wsgi

o eseguire come processo demone usando l'opzione -D

3. All'avvio corretto di gunicorn, le seguenti righe appariranno in console

Starting gunicorn 19.5.0

Listening at: http://127.0.0.1:[port number] ([pid])

.... (altre informazioni aggiuntive sul server gunicorn)

Distribuzione con Heroku

1. Scarica Heroku Toolbelt .

2. Passa alla radice dei sorgenti della tua app Django. Avrai bisogno di TK

3. Digita heroku create [app_name] . heroku create [app_name] . Se non si fornisce un nome app,
Heroku ne genererà uno a caso. L'URL della tua app sarà http://[app name].herokuapp.com

4. Crea un file di testo con il nome Procfile . Non mettere un'estensione alla fine.

web: <bash command to start production server>

Se hai un processo di lavoro, puoi aggiungerlo anche tu. Aggiungi un'altra riga
nel formato: worker-name: <bash command to start worker>

5. Aggiungi un requisito.txt.

• Se si utilizza un ambiente virtuale, eseguire pip freeze > requirements.txt


• Altrimenti, ottieni un ambiente virtuale! . Puoi anche elencare manualmente i pacchetti
Python di cui hai bisogno, ma questo non sarà trattato in questo tutorial.

https://riptutorial.com/it/home 50
6. È il momento dello spiegamento!

1. git push heroku master

Heroku ha bisogno di un repository git o di una cartella dropbox per fare


distribuzioni. In alternativa puoi configurare il ricaricamento automatico da un
repository GitHub su heroku.com , ma non lo heroku.com in questo tutorial.

2. heroku ps:scale web=1

Questo ridimensiona il numero di "dynos" web in uno. Qui puoi saperne di più sui
dynos .

3. heroku open o vai a http://app-name.herokuapp.com

Suggerimento: heroku open apre l'URL della tua app heroku nel browser
predefinito.

7. Aggiungi componenti aggiuntivi . Dovrai configurare la tua app Django per legare con i
database forniti in Heroku come "componenti aggiuntivi". Questo esempio non copre questo,
ma un altro esempio è nella pipeline sulla distribuzione di database in Heroku.

Distribuzione remota semplice fabfile.py

Fabric è una libreria Python (2.5-2.7) e uno strumento da riga di comando per semplificare l'uso di
SSH per la distribuzione delle applicazioni o le attività di amministrazione dei sistemi. Ti permette
di eseguire funzioni arbitrarie di Python tramite la riga di comando.

Installa il tessuto tramite il pip install fabric


Crea fabfile.py nella tua directory principale:

#myproject/fabfile.py
from fabric.api import *

@task
def dev():
# details of development server
env.user = # your ssh user
env.password = #your ssh password
env.hosts = # your ssh hosts (list instance, with comma-separated hosts)
env.key_filename = # pass to ssh key for github in your local keyfile

@task
def release():
# details of release server
env.user = # your ssh user
env.password = #your ssh password
env.hosts = # your ssh hosts (list instance, with comma-separated hosts)
env.key_filename = # pass to ssh key for github in your local keyfile

@task
def run():
with cd('path/to/your_project/'):
with prefix('source ../env/bin/activate'):

https://riptutorial.com/it/home 51
# activate venv, suppose it appear in one level higher
# pass commands one by one
run('git pull')
run('pip install -r requirements.txt')
run('python manage.py migrate --noinput')
run('python manage.py collectstatic --noinput')
run('touch reload.txt')

Per eseguire il file, usa semplicemente il comando fab :

$ fab dev run # for release server, `fab release run`

Nota: non è possibile configurare le chiavi ssh per github e digitare manualmente login e
password, mentre fabfile esegue, lo stesso con le chiavi.

Usando Heroku Django Starter Template.

Se hai intenzione di ospitare il tuo sito Django su Heroku, puoi iniziare il tuo progetto usando il
Template di avvio Heroku Django:

django-admin.py startproject --template=https://github.com/heroku/heroku-django-


template/archive/master.zip --name=Procfile YourProjectName

Ha una configurazione pronta per la produzione per file statici, impostazioni database, Gunicorn,
ecc. E miglioramenti alla funzionalità di file statici di Django tramite WhiteNoise. Questo ti farà
risparmiare tempo, è completamente pronto per l'hosting su Heroku. Costruisci il tuo sito web in
cima a questo modello

Per distribuire questo modello su Heroku:

git init
git add -A
git commit -m "Initial commit"

heroku create
git push heroku master

heroku run python manage.py migrate

Questo è tutto!

Istruzioni di distribuzione di Django. Nginx + Gunicorn + Supervisor su Linux


(Ubuntu)

Tre strumenti di base.

1. nginx: server HTTP e reverse proxy gratuito, open source e ad alte prestazioni, con
prestazioni elevate;
2. gunicorn - "Green Unicorn" è un server HTTP WSGI Python per UNIX (necessario per
gestire il server);

https://riptutorial.com/it/home 52
3. supervisore - un sistema client / server che consente agli utenti di monitorare e controllare
un numero di processi su sistemi operativi UNIX-like. Utilizzato quando l'app o il sistema si
bloccano, riavvia la tua webcam django / sedano / sedano, ecc;

Per semplificare, supponiamo che la tua app si trovi in questa directory: /home/root/app/src/ e
useremo l'utente root (ma dovresti creare un utente separato per la tua app). Anche il nostro
ambiente virtuale si troverà in /home/root/app/env/ path.

Nginx
Iniziamo con nginx. Se nginx non è già sulla macchina, installalo con sudo apt-get install nginx .
In seguito devi creare un nuovo file di configurazione nella tua directory nginx /etc/nginx/sites-
enabled/yourapp.conf . Se c'è un file chiamato default.conf - rimuovilo.

Codice muggito in un file conf nginx, che proverà ad eseguire il tuo servizio usando il file socket;
Più avanti ci sarà una configurazione di gunicorn. Il file socket è usato qui per comunicare tra
nginx e gunicorn. Può anche essere fatto usando le porte.

# your application name; can be whatever you want


upstream yourappname {
server unix:/home/root/app/src/gunicorn.sock fail_timeout=0;
}

server {
# root folder of your application
root /home/root/app/src/;

listen 80;
# server name, your main domain, all subdomains and specific subdomains
server_name yourdomain.com *.yourdomain.com somesubdomain.yourdomain.com

charset utf-8;

client_max_body_size 100m;

# place where logs will be stored;


# folder and files have to be already located there, nginx will not create
access_log /home/root/app/src/logs/nginx-access.log;
error_log /home/root/app/src/logs/nginx-error.log;

# this is where your app is served (gunicorn upstream above)


location / {
uwsgi_pass yourappname;
include uwsgi_params;
}

# static files folder, I assume they will be used


location /static/ {
alias /home/root/app/src/static/;
}

# media files folder


location /media/ {
alias /home/root/app/src/media/;
}

https://riptutorial.com/it/home 53
}

GUNICORN
Ora il nostro script GUNICORN, che sarà responsabile dell'esecuzione dell'applicazione django
sul server. La prima cosa è installare gunicorn in ambiente virtuale con pip install gunicorn .

#!/bin/bash

ME="root"
DJANGODIR=/home/root/app/src # django app dir
SOCKFILE=/home/root/app/src/gunicorn.sock # your sock file - do not create it manually
USER=root
GROUP=webapps
NUM_WORKERS=3
DJANGO_SETTINGS_MODULE=yourapp.yoursettings
DJANGO_WSGI_MODULE=yourapp.wsgi
echo "Starting $NAME as `whoami`"

# Activate the virtual environment


cd $DJANGODIR

source /home/root/app/env/bin/activate
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DJANGODIR:$PYTHONPATH

# Create the run directory if it doesn't exist


RUNDIR=$(dirname $SOCKFILE)
test -d $RUNDIR || mkdir -p $RUNDIR

# Start your Django Gunicorn


# Programs meant to be run under supervisor should not daemonize themselves (do not use --
daemon)
exec /home/root/app/env/bin/gunicorn ${DJANGO_WSGI_MODULE}:application \
--name root \
--workers $NUM_WORKERS \
--user=$USER --group=$GROUP \
--bind=unix:$SOCKFILE \
--log-level=debug \
--log-file=-

per poter eseguire lo script di avvio di gunicorn, è necessario che la modalità di esecuzione sia
abilitata

sudo chmod u+x /home/root/app/src/gunicorn_start

ora sarai in grado di avviare il tuo server gunicorn semplicemente usando ./gunicorn_start

SUPERVISORE
Come detto all'inizio, vogliamo che la nostra applicazione venga riavviata quando fallisce un
supervisore. Se supervisore non è ancora installato sul server con sudo apt-get install supervisor

https://riptutorial.com/it/home 54
.

Al primo installatore supervisore. Quindi crea un file .conf nella directory principale
/etc/supervisor/conf.d/your_conf_file.conf

contenuto del file di configurazione:

[program:yourappname]
command = /home/root/app/src/gunicorn_start
user = root
stdout_logfile = /home/root/app/src/logs/gunicorn_supervisor.log
redirect_stderr = true

Breve brief, [program:youappname] è richiesto all'inizio, sarà il nostro identificatore. anche


stdout_logfile è un file in cui verranno memorizzati i registri, sia l'accesso che gli errori.

Fatto ciò, dobbiamo dire al nostro supervisore che abbiamo appena aggiunto un nuovo file di
configurazione. Per farlo, c'è un processo diverso per la diversa versione di Ubuntu.

Per Ubuntu version 14.04 or lesser , semplicemente esegui quei comandi:

-> rilegge tutti i file di configurazione all'interno del catalogo supervisore


sudo supervisorctl reread
che dovrebbe essere stampato: yourappname: available

-> aggiorna il supervisore ai file di configurazione appena aggiunti;


sudo supervisorctl update
dovrebbe stampare yourappname: aggiunto gruppo di processi

Per Ubuntu 16.04 Esegui:

sudo service supervisor restart

e per verificare se la tua app funziona correttamente, esegui

sudo supervisorctl status yourappname

Questo dovrebbe mostrare:

yourappname RUNNING pid 18020, uptime 0:00:50

Per ottenere la dimostrazione dal vivo di questa procedura, naviga questo video .

Distribuzione locale senza impostazione di apache / nginx

Il modo consigliato per l'implementazione della produzione richiede l'uso di Apache / Nginx per
servire il contenuto statico. Pertanto, quando DEBUG è falso statico e il contenuto multimediale non
viene caricato. Tuttavia, possiamo caricare il contenuto statico nella distribuzione senza dover
configurare il server Apache / Nginx per la nostra app utilizzando:

python manage.py runserver --insecure

Questo è destinato esclusivamente per la distribuzione locale (ad esempio, LAN) e non dovrebbe

https://riptutorial.com/it/home 55
mai essere utilizzato nella produzione ed è disponibile solo se lo staticfiles app è in del progetto
INSTALLED_APPS impostazione.

Leggi Distribuzione online: https://riptutorial.com/it/django/topic/2792/distribuzione

https://riptutorial.com/it/home 56
Capitolo 15: Django dalla riga di comando.
Osservazioni
Mentre Django è principalmente per applicazioni web, ha un ORM potente e facile da usare che
può essere utilizzato anche per applicazioni e script da riga di comando. Esistono due diversi
approcci che possono essere utilizzati. Il primo è di creare un comando di gestione personalizzato
e il secondo di inizializzare l'ambiente Django all'inizio del tuo script.

Examples
Django dalla riga di comando.

Supponendo di aver impostato un progetto django e il file delle impostazioni si trova in un'app
chiamata main, ecco come si inizializza il codice

import os, sys

# Setup environ
sys.path.append(os.getcwd())
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "main.settings")

# Setup django
import django
django.setup()

# rest of your imports go here

from main.models import MyModel

# normal python code that makes use of Django models go here

for obj in MyModel.objects.all():


print obj

Quanto sopra può essere eseguito come

python main/cli.py

Leggi Django dalla riga di comando. online: https://riptutorial.com/it/django/topic/5848/django-


dalla-riga-di-comando-

https://riptutorial.com/it/home 57
Capitolo 16: Django e reti sociali
Parametri

Ambientazione fa

Pratiche impostazioni di base che vanno


con Django-Allauth (che uso la maggior
Alcune configurazioni
parte del tempo). Per ulteriori opzioni di
configurazione, vedi Configurazioni

Specifica il metodo di accesso da utilizzare,


indipendentemente dal fatto che l'utente
effettui l'accesso immettendo il proprio
ACCOUNT_AUTHENTICATION_METHOD (=
nome utente, l'indirizzo e-mail o uno di
"nomeutente" o "email" o "nomeutente_email")
entrambi. L'impostazione su "email"
richiede ACCOUNT_EMAIL_REQUIRED =
True

ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS Determina la data di scadenza delle e-mail


(= 3) di conferma dell'email (numero di giorni).

L'utente è tenuto a consegnare un indirizzo


ACCOUNT_EMAIL_REQUIRED (= Falso) e-mail al momento della registrazione.
Questo va di pari passo con l'impostazione
ACCOUNT_AUTHENTICATION_METHOD

Determina il metodo di verifica dell'e-mail


durante la registrazione: scegli uno tra
"obbligatorio", "facoltativo" o "nessuno". Se
impostato su "obbligatorio", l'utente è
bloccato dal login fino a quando l'indirizzo
email non viene verificato. Scegliere
ACCOUNT_EMAIL_VERIFICATION (= "opzionale")
"facoltativo" o "nessuno" per consentire
accessi con un indirizzo e-mail non
verificato. In caso di "facoltativo", la posta di
verifica dell'e-mail viene comunque inviata,
mentre in caso di "nessuno" non vengono
inviate mail di verifica e-mail.

Numero di tentativi di accesso non riusciti.


Al superamento di questo numero, all'utente
è proibito accedere per i secondi
ACCOUNT_LOGIN_ATTEMPTS_LIMIT (= 5)
ACCOUNT_LOGIN_ATTEMPTS_TIMEOUT
specificati. Mentre questo protegge la vista
di login di allauth, non protegge il login

https://riptutorial.com/it/home 58
Ambientazione fa

dell'amministratore di Django dall'essere


bruto forzato.

Determina se l'utente viene disconnesso


ACCOUNT_LOGOUT_ON_PASSWORD_CHANGE (=
automaticamente dopo aver modificato o
Falso)
impostato la propria password.

Dizionario contenente impostazioni


SOCIALACCOUNT_PROVIDERS (= dict)
specifiche del provider.

Examples
Modo semplice: python-social-auth

python-social-auth è un framework che semplifica l'autenticazione sociale e il meccanismo


di autorizzazione. Contiene molti social backend (Facebook, Twitter, Github, LinkedIn, ecc.)

INSTALLARE

Per prima cosa dobbiamo installare il pacchetto python-social-auth con

pip install python-social-auth

o scarica il codice da github. Ora è un buon momento per aggiungere questo al tuo file
requirements.txt .

CONFIGURAZIONE di settings.py

In settings.py aggiungi:

INSTALLED_APPS = (
...
'social.apps.django_app.default',
...
)

CONFIGURARE BACKENDS

AUTHENTICATION_BACKENDS contiene i backend che useremo e dobbiamo solo mettere ciò di


cui abbiamo bisogno.

AUTHENTICATION_BACKENDS = (
'social.backends.open_id.OpenIdAuth',
'social.backends.google.GoogleOpenId',
'social.backends.google.GoogleOAuth2',
'social.backends.google.GoogleOAuth',
'social.backends.twitter.TwitterOAuth',
'social.backends.yahoo.YahooOpenId',

https://riptutorial.com/it/home 59
...
'django.contrib.auth.backends.ModelBackend',
)

Il tuo progetto settings.py potrebbe non avere ancora un campo AUTHENTICATION_BACKENDS . Se


questo è il caso aggiungi il campo. Assicurati di non perdere
'django.contrib.auth.backends.ModelBackend', poiché gestisce l'accesso tramite nome utente /
password.

Se utilizziamo ad esempio Facebook e i backend di Linkedin, dobbiamo aggiungere le chiavi API

SOCIAL_AUTH_FACEBOOK_KEY = 'YOURFACEBOOKKEY'
SOCIAL_AUTH_FACEBOOK_SECRET = 'YOURFACEBOOKSECRET'

SOCIAL_AUTH_LINKEDIN_KEY = 'YOURLINKEDINKEY'
SOCIAL_AUTH_LINKEDIN_SECRET = 'YOURLINKEDINSECRET'

Nota : è possibile ottenere le chiavi Nedded negli sviluppatori di Facebook e negli sviluppatori di
Linkedin e qui è possibile visualizzare l'elenco completo e il suo rispettivo modo di specificare la
chiave API e il segreto chiave.

Nota sulle chiavi segrete: le chiavi segrete dovrebbero essere tenute segrete. Ecco una
spiegazione dello Stack Overflow che è utile. Questo tutorial è utile per l'apprendimento delle
variabili ambientali.

TEMPLATE_CONTEXT_PROCESSORS aiuterà a reindirizzamenti, backend e altre cose, ma


all'inizio abbiamo solo bisogno di questi:

TEMPLATE_CONTEXT_PROCESSORS = (
...
'social.apps.django_app.context_processors.backends',
'social.apps.django_app.context_processors.login_redirect',
...
)

In Django 1.8 l'impostazione di TEMPLATE_CONTEXT_PREPROCESSORS come mostrato sopra era


deprecata. Se questo è il tuo caso, lo aggiungi all'interno del comando TEMPLATES . Il tuo dovrebbe
sembrare qualcosa di simile a questo:

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, "templates")],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',

https://riptutorial.com/it/home 60
'social.apps.django_app.context_processors.backends',
'social.apps.django_app.context_processors.login_redirect',
],
},
},
]

UTILIZZO DI UN UTENTE PERSONALIZZATO

Se utilizzi un modello utente personalizzato e desideri associarlo, aggiungi la seguente riga


(ancora in settings.py )

SOCIAL_AUTH_USER_MODEL = 'somepackage.models.CustomUser'

CustomUser è un modello che eredita o Abstract dall'utente predefinito.

CONFIGURARE urls.py

# if you haven't imported inlcude make sure you do so at the top of your file
from django.conf.urls import url, include

urlpatterns = patterns('',
...
url('', include('social.apps.django_app.urls', namespace='social'))
...
)

Successivamente è necessario sincronizzare il database per creare i modelli necessari:

./manage.py migrate

Finalmente possiamo giocare!

in alcuni template è necessario aggiungere qualcosa come questo:

<a href="{% url 'social:begin' 'facebook' %}?next={{ request.path }}">Login with


Facebook</a>
<a href="{% url 'social:begin' 'linkedin' %}?next={{ request.path }}">Login with
Linkedin</a>

se usi un altro backend cambia semplicemente 'facebook' con il nome del backend.

Registrazione degli utenti

Una volta registrati gli utenti, probabilmente vorrai creare la funzionalità per reinserirli. In alcuni
modelli, probabilmente vicino a dove è stato mostrato il modello di accesso, aggiungi il seguente
tag:

<a href="{% url 'logout' %}">Logout</a>

https://riptutorial.com/it/home 61
<a href="/logout">Logout</a>

Dovrai modificare il tuo file urls.py con codice simile a:

url(r'^logout/$', views.logout, name='logout'),

Infine modifica il tuo file views.py con codice simile a:

def logout(request):
auth_logout(request)
return redirect('/')

Utilizzando Django Allauth

Per tutti i miei progetti, Django-Allauth ne è rimasto uno che è facile da configurare e viene fornito
con molte funzionalità tra cui, a titolo esemplificativo:

• Oltre 50 autenticazioni di social network


• Mescolare l'iscrizione di account locali e social
• Più account sociali
• Registrazione istantanea opzionale per account social: nessuna domanda
• Gestione dell'indirizzo e-mail (più indirizzi e-mail, impostazione di un primario)
• Flusso dimenticato dalla password Flusso di verifica dell'indirizzo e-mail

Se sei interessato a sporcarti le mani, Django-Allauth si toglie di mezzo, con configurazioni


aggiuntive per ottimizzare il processo e l'uso del tuo sistema di autenticazione.

I passaggi seguenti presuppongono che tu stia utilizzando Django 1.10+

Passaggi di installazione:

pip install django-allauth

Nel file settings.py , apporta le seguenti modifiche:

# Specify the context processors as follows:


TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
# Already defined Django-related contexts here

# `allauth` needs this from django. It is there by default,


# unless you've devilishly taken it away.
'django.template.context_processors.request',
],
},
},
]

https://riptutorial.com/it/home 62
AUTHENTICATION_BACKENDS = (
# Needed to login by username in Django admin, regardless of `allauth`
'django.contrib.auth.backends.ModelBackend',

# `allauth` specific authentication methods, such as login by e-mail


'allauth.account.auth_backends.AuthenticationBackend',
)

INSTALLED_APPS = (
# Up here is all your default installed apps from Django

# The following apps are required:


'django.contrib.auth',
'django.contrib.sites',

'allauth',
'allauth.account',
'allauth.socialaccount',

# include the providers you want to enable:


'allauth.socialaccount.providers.google',
'allauth.socialaccount.providers.facebook',
)

# Don't forget this little dude.


SITE_ID = 1

Fatto con le modifiche nel file settings.py sopra, passa al file urls.py Può essere il yourapp/urls.py
o il tuo ProjectName/urls.py Normalmente, preferisco ProjectName/urls.py

urlpatterns = [
# other urls here
url(r'^accounts/', include('allauth.urls')),
# other urls here
]

Semplicemente aggiungendo l' include('allauth.urls') , ti dà questi URL gratuitamente:

^accounts/ ^ ^signup/$ [name='account_signup']


^accounts/ ^ ^login/$ [name='account_login']
^accounts/ ^ ^logout/$ [name='account_logout']
^accounts/ ^ ^password/change/$ [name='account_change_password']
^accounts/ ^ ^password/set/$ [name='account_set_password']
^accounts/ ^ ^inactive/$ [name='account_inactive']
^accounts/ ^ ^email/$ [name='account_email']
^accounts/ ^ ^confirm-email/$ [name='account_email_verification_sent']
^accounts/ ^ ^confirm-email/(?P<key>[-:\w]+)/$ [name='account_confirm_email']
^accounts/ ^ ^password/reset/$ [name='account_reset_password']
^accounts/ ^ ^password/reset/done/$ [name='account_reset_password_done']
^accounts/ ^ ^password/reset/key/(?P<uidb36>[0-9A-Za-z]+)-(?P<key>.+)/$
[name='account_reset_password_from_key']
^accounts/ ^ ^password/reset/key/done/$ [name='account_reset_password_from_key_done']
^accounts/ ^social/
^accounts/ ^google/
^accounts/ ^twitter/
^accounts/ ^facebook/
^accounts/ ^facebook/login/token/$ [name='facebook_login_by_token']

https://riptutorial.com/it/home 63
Infine, python ./manage.py migrate per eseguire il commit delle migrazioni di Django-allauth nel
Database.

Come al solito, per poter accedere alla tua app utilizzando qualsiasi social network che hai
aggiunto, dovrai aggiungere i dettagli dell'account social della rete.

Accedi all'amministratore di Django ( localhost:8000/admin ) e in Social Applications aggiungendo i


dettagli del tuo account social.

Potrebbe essere necessario disporre di account presso ciascun provider di autenticazione per
ottenere dettagli da compilare nelle sezioni Applicazioni sociali.

Per configurazioni dettagliate di ciò che puoi avere e modificare, consulta la pagina Configurazioni
.

Leggi Django e reti sociali online: https://riptutorial.com/it/django/topic/4743/django-e-reti-sociali

https://riptutorial.com/it/home 64
Capitolo 17: Django Rest Framework
Examples
API di sola lettura barebone semplice

Supponendo che tu abbia un modello che assomiglia a quanto segue, ci metteremo a correre con
un'API di sola lettura barebone semplice guidata da Django REST Framework ("DRF").

models.py

class FeedItem(models.Model):
title = models.CharField(max_length=100, blank=True)
url = models.URLField(blank=True)
style = models.CharField(max_length=100, blank=True)
description = models.TextField(blank=True)

Il serializzatore è il componente che prenderà tutte le informazioni dal modello Django (in questo
caso il FeedItem ) e lo trasformerà in JSON. È molto simile alla creazione di classi di form in
Django. Se hai esperienza in questo, questo sarà molto comodo per te.

serializers.py

from rest_framework import serializers


from . import models

class FeedItemSerializer(serializers.ModelSerializer):
class Meta:
model = models.FeedItem
fields = ('title', 'url', 'description', 'style')

views.py

DRF offre molte classi di visualizzazione per gestire una varietà di casi d'uso. In questo esempio,
avremo solo un'API di sola lettura , quindi, anziché utilizzare un viewet più completo o una serie
di viste generiche correlate, utilizzeremo una singola sottoclasse di ListAPIView di DRF.

Lo scopo di questa classe è di collegare i dati con il serializzatore e avvolgerli tutti insieme per un
oggetto risposta.

from rest_framework import generics


from . import serializers, models

class FeedItemList(generics.ListAPIView):
serializer_class = serializers.FeedItemSerializer
queryset = models.FeedItem.objects.all()

urls.py

https://riptutorial.com/it/home 65
Assicurati di puntare il percorso verso la tua vista DRF.

from django.conf.urls import url


from . import views

urlpatterns = [
...
url(r'path/to/api', views.FeedItemList.as_view()),
]

Leggi Django Rest Framework online: https://riptutorial.com/it/django/topic/7341/django-rest-


framework

https://riptutorial.com/it/home 66
Capitolo 18: django-filtro
Examples
Usa il filtro Django con CBV

django-filter è un sistema generico per il filtraggio di Django QuerySet in base alle selezioni
dell'utente. La documentazione lo utilizza in una vista basata sulle funzioni come modello di
prodotto:

from django.db import models

class Product(models.Model):
name = models.CharField(max_length=255)
price = models.DecimalField()
description = models.TextField()
release_date = models.DateField()
manufacturer = models.ForeignKey(Manufacturer)

Il filtro sarà il seguente:

import django_filters

class ProductFilter(django_filters.FilterSet):
name = django_filters.CharFilter(lookup_expr='iexact')

class Meta:
model = Product
fields = ['price', 'release_date']

Per utilizzare questo in un CBV, eseguire l'override di get_queryset() di ListView, quindi restituire il
querset filtri filtrato:

from django.views.generic import ListView


from .filters import ProductFilter

class ArticleListView(ListView):
model = Product

def get_queryset(self):
qs = self.model.objects.all()
product_filtered_list = ProductFilter(self.request.GET, queryset=qs)
return product_filtered_list.qs

È possibile accedere agli oggetti filtrati nelle viste, ad esempio con paginazione, in f.qs Questo
impaginerà l'elenco degli oggetti filtrati.

Leggi django-filtro online: https://riptutorial.com/it/django/topic/6101/django-filtro

https://riptutorial.com/it/home 67
Capitolo 19: Esecuzione di Celery con
Supervisor
Examples
Configurazione del sedano

SEDANO
1. Installazione - pip install django-celery

2. Inserisci

3. Struttura di progetto di base.

- src/
- bin/celery_worker_start # will be explained later on
- logs/celery_worker.log
- stack/__init __.py
- stack/celery.py
- stack/settings.py
- stack/urls.py
- manage.py

4. Aggiungi il file celery.py al tuo stack/stack/ cartella.

from __future__ import absolute_import


import os
from celery import Celery
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'stack.settings')
from django.conf import settings # noqa
app = Celery('stack')
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)

5. al tuo stack/stack/__init__.py aggiungi il seguente codice:

from __future__ import absolute_import


from .celery import app as celery_app # noqa

6. Crea un'attività e contrassegnala per esempio come @shared_task()

@shared_task()
def add(x, y):
print("x*y={}".format(x*y))

7. Eseguendo il lavoratore del sedano "a mano":

https://riptutorial.com/it/home 68
celery -A stack worker -l info se vuoi aggiungere anche

Supervisore in esecuzione

1. Crea uno script per avviare il gestore di sedano. Inserisci il tuo script nella tua app. Ad
esempio: stack/bin/celery_worker_start

#!/bin/bash

NAME="StackOverflow Project - celery_worker_start"

PROJECT_DIR=/home/stackoverflow/apps/proj/proj/
ENV_DIR=/home/stackoverflow/apps/proj/env/

echo "Starting $NAME as `whoami`"

# Activate the virtual environment


cd "${PROJECT_DIR}"

if [ -d "${ENV_DIR}" ]
then
. "${ENV_DIR}bin/activate"
fi

celery -A stack --loglevel='INFO'

2. Aggiungi i diritti di esecuzione allo script appena creato:

chmod u+x bin/celery_worker_start

3. Installa supervisore (salta questo test se il supervisore è già installato)

apt-get install supervisor

4. Aggiungi il file di configurazione per il tuo supervisore per iniziare il sedano. Collocarlo in
/etc/supervisor/conf.d/stack_supervisor.conf

[program:stack-celery-worker]
command = /home/stackoverflow/apps/stack/src/bin/celery_worker_start
user = polsha
stdout_logfile = /home/stackoverflow/apps/stack/src/logs/celery_worker.log
redirect_stderr = true
environment = LANG = en_US.UTF-8,LC_ALL = en_US.UTF-8
numprocs = 1
autostart = true
autorestart = true
startsecs = 10
stopwaitsecs = 600
priority = 998

5. Rileggere e aggiornare il supervisore

sudo supervisorctl reread


stack-celery-worker: available
sudo supervisorctl update
stack-celery-worker: added process group

https://riptutorial.com/it/home 69
6. Comandi di base

sudo supervisorctl status stack-celery-worker


stack-celery-worker RUNNING pid 18020, uptime 0:00:50
sudo supervisorctl stop stack-celery-worker
stack-celery-worker: stopped
sudo supervisorctl start stack-celery-worker
stack-celery-worker: started
sudo supervisorctl restart stack-celery-worker
stack-celery-worker: stopped
stack-celery-worker: started

Celery + RabbitMQ con Supervisor

Celery richiede a un broker di gestire il passaggio dei messaggi. Usiamo RabbitMQ perché è facile
da configurare ed è ben supportato.

Installa rabbitmq utilizzando il seguente comando

sudo apt-get install rabbitmq-server

Una volta completata l'installazione, creare un utente, aggiungere un host virtuale e impostare le
autorizzazioni.

sudo rabbitmqctl add_user myuser mypassword


sudo rabbitmqctl add_vhost myvhost
sudo rabbitmqctl set_user_tags myuser mytag
sudo rabbitmqctl set_permissions -p myvhost myuser ".*" ".*" ".*"

Per avviare il server:

sudo rabbitmq-server

Possiamo installare sedano con pip:

pip install celery

Nel tuo file Django settings.py, l'URL del tuo broker sarebbe quindi simile

BROKER_URL = 'amqp://myuser:mypassword@localhost:5672/myvhost'

Ora inizia il sedano

celery -A your_app worker -l info

Questo comando avvia un operatore di Celery per eseguire tutte le attività definite nell'app django.

Supervisor è un programma Python che consente di controllare e mantenere in esecuzione


qualsiasi processo unix. Può anche riavviare i processi bloccati. Lo usiamo per assicurarci che i

https://riptutorial.com/it/home 70
lavoratori di Celery siano sempre in esecuzione.

Innanzitutto, installa supervisore

sudo apt-get install supervisor

Crea il tuo file_proj.conf nel tuo supervisore conf.d (/etc/supervisor/conf.d/your_proj.conf):

[program:your_proj_celery]
command=/home/your_user/your_proj/.venv/bin/celery --app=your_proj.celery:app worker -l info
directory=/home/your_user/your_proj
numprocs=1
stdout_logfile=/home/your_user/your_proj/logs/celery-worker.log
stderr_logfile=/home/your_user/your_proj/logs/low-worker.log
autostart=true
autorestart=true
startsecs=10

Una volta che il nostro file di configurazione è stato creato e salvato, possiamo informare il
Supervisore del nostro nuovo programma attraverso il comando supervisorctl. Per prima cosa
chiediamo a Supervisor di cercare eventuali configurazioni di programma nuove o modificate nella
directory /etc/supervisor/conf.d con:

sudo supervisorctl reread

Seguito dicendogli di applicare qualsiasi modifica con:

sudo supervisorctl update

Una volta che i nostri programmi sono in esecuzione, ci sarà indubbiamente un momento in cui
vogliamo fermarci, riavviarci o vedere il loro stato.

sudo supervisorctl status

Per riavviare l'istanza di sedano:

sudo supervisorctl restart your_proj_celery

Leggi Esecuzione di Celery con Supervisor online:


https://riptutorial.com/it/django/topic/7091/esecuzione-di-celery-con-supervisor

https://riptutorial.com/it/home 71
Capitolo 20: Estensione o sostituzione del
modello utente
Examples
Modello utente personalizzato con email come campo di accesso principale.

models.py:

from __future__ import unicode_literals


from django.db import models
from django.contrib.auth.models import (
AbstractBaseUser, BaseUserManager, PermissionsMixin)
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _

class UserManager(BaseUserManager):
def _create_user(self, email,password, is_staff, is_superuser, **extra_fields):
now = timezone.now()
if not email:
raise ValueError('users must have an email address')
email = self.normalize_email(email)
user = self.model(email = email,
is_staff = is_staff,
is_superuser = is_superuser,
last_login = now,
date_joined = now,
**extra_fields)
user.set_password(password)
user.save(using = self._db)
return user

def create_user(self, email, password=None, **extra_fields):


user = self._create_user(email, password, False, False, **extra_fields)
return user

def create_superuser(self, email, password, **extra_fields):


user = self._create_user(email, password, True, True, **extra_fields)
return user

class User(AbstractBaseUser,PermissionsMixin):
"""My own custom user class"""

email = models.EmailField(max_length=255, unique=True, db_index=True,


verbose_name=_('email address'))
date_joined = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)

objects = UserManager()

USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []

https://riptutorial.com/it/home 72
class Meta:
verbose_name = _('user')
verbose_name_plural = _('users')

def get_full_name(self):
"""Return the email."""
return self.email

def get_short_name(self):
"""Return the email."""
return self.email

forms.py:

from django import forms


from django.contrib.auth.forms import UserCreationForm
from .models import User

class RegistrationForm(UserCreationForm):
email = forms.EmailField(widget=forms.TextInput(
attrs={'class': 'form-control','type':'text','name': 'email'}),
label="Email")
password1 = forms.CharField(widget=forms.PasswordInput(
attrs={'class':'form-control','type':'password', 'name':'password1'}),
label="Password")
password2 = forms.CharField(widget=forms.PasswordInput(
attrs={'class':'form-control','type':'password', 'name': 'password2'}),
label="Password (again)")

'''added attributes so as to customise for styling, like bootstrap'''


class Meta:
model = User
fields = ['email','password1','password2']
field_order = ['email','password1','password2']

def clean(self):
"""
Verifies that the values entered into the password fields match
NOTE : errors here will appear in 'non_field_errors()'
"""
cleaned_data = super(RegistrationForm, self).clean()
if 'password1' in self.cleaned_data and 'password2' in self.cleaned_data:
if self.cleaned_data['password1'] != self.cleaned_data['password2']:
raise forms.ValidationError("Passwords don't match. Please try again!")
return self.cleaned_data

def save(self, commit=True):


user = super(RegistrationForm,self).save(commit=False)
user.set_password(self.cleaned_data['password1'])
if commit:
user.save()
return user

#The save(commit=False) tells Django to save the new record, but dont commit it to the
database yet

class AuthenticationForm(forms.Form): # Note: forms.Form NOT forms.ModelForm


email = forms.EmailField(widget=forms.TextInput(
attrs={'class': 'form-control','type':'text','name': 'email','placeholder':'Email'}),

https://riptutorial.com/it/home 73
label='Email')
password = forms.CharField(widget=forms.PasswordInput(
attrs={'class':'form-control','type':'password', 'name':
'password','placeholder':'Password'}),
label='Password')

class Meta:
fields = ['email', 'password']

views.py:

from django.shortcuts import redirect, render, HttpResponse


from django.contrib.auth import login as django_login, logout as django_logout, authenticate
as django_authenticate
#importing as such so that it doesn't create a confusion with our methods and django's default
methods

from django.contrib.auth.decorators import login_required


from .forms import AuthenticationForm, RegistrationForm

def login(request):
if request.method == 'POST':
form = AuthenticationForm(data = request.POST)
if form.is_valid():
email = request.POST['email']
password = request.POST['password']
user = django_authenticate(email=email, password=password)
if user is not None:
if user.is_active:
django_login(request,user)
return redirect('/dashboard') #user is redirected to dashboard
else:
form = AuthenticationForm()

return render(request,'login.html',{'form':form,})

def register(request):
if request.method == 'POST':
form = RegistrationForm(data = request.POST)
if form.is_valid():
user = form.save()
u = django_authenticate(user.email = user, user.password = password)
django_login(request,u)
return redirect('/dashboard')
else:
form = RegistrationForm()

return render(request,'register.html',{'form':form,})

def logout(request):
django_logout(request)
return redirect('/')

@login_required(login_url ="/")
def dashboard(request):
return render(request, 'dashboard.html',{})

settings.py:

https://riptutorial.com/it/home 74
AUTH_USER_MODEL = 'myapp.User'

admin.py

from django.contrib import admin


from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import Group
from .models import User

class UserAdmin(BaseUserAdmin):
list_display = ('email','is_staff')
list_filter = ('is_staff',)
fieldsets = ((None,
{'fields':('email','password')}), ('Permissions',{'fields':('is_staff',)}),)
add_fieldsets = ((None, {'classes': ('wide',), 'fields': ('email', 'password1',
'password2')}),)
search_fields =('email',)
ordering = ('email',)
filter_horizontal = ()

admin.site.register(User, UserAdmin)
admin.site.unregister(Group)

Usa l'email come username e sbarazzati del campo `username`

Se si desidera eliminare il campo del username e utilizzare l'e email come identificativo utente
univoco, sarà necessario creare un modello User personalizzato estendendo AbstractBaseUser
anziché AbstractUser . Infatti, username ed email sono definiti in AbstractUser e non è possibile
sovrascriverli. Ciò significa che dovrai anche ridefinire tutti i campi che desideri definiti in
AbstractUser .

from django.contrib.auth.models import (


AbstractBaseUser, PermissionsMixin, BaseUserManager,
)
from django.db import models
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _

class UserManager(BaseUserManager):

use_in_migrations = True

def _create_user(self, email, password, **extra_fields):


if not email:
raise ValueError('The given email must be set')
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user

def create_user(self, email, password=None, **extra_fields):


extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
return self._create_user(email, password, **extra_fields)

https://riptutorial.com/it/home 75
def create_superuser(self, email, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)

if extra_fields.get('is_staff') is not True:


raise ValueError('Superuser must have is_staff=True.')
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')

return self._create_user(email, password, **extra_fields)

class User(AbstractBaseUser, PermissionsMixin):


"""PermissionsMixin contains the following fields:
- `is_superuser`
- `groups`
- `user_permissions`
You can omit this mix-in if you don't want to use permissions or
if you want to implement your own permissions logic.
"""

class Meta:
verbose_name = _("user")
verbose_name_plural = _("users")
db_table = 'auth_user'
# `db_table` is only needed if you move from the existing default
# User model to a custom one. This enables to keep the existing data.

USERNAME_FIELD = 'email'
"""Use the email as unique username."""

REQUIRED_FIELDS = ['first_name', 'last_name']

GENDER_MALE = 'M'
GENDER_FEMALE = 'F'
GENDER_CHOICES = [
(GENDER_MALE, _("Male")),
(GENDER_FEMALE, _("Female")),
]

email = models.EmailField(
verbose_name=_("email address"), unique=True,
error_messages={
'unique': _(
"A user is already registered with this email address"),
},
)
gender = models.CharField(
max_length=1, blank=True, choices=GENDER_CHOICES,
verbose_name=_("gender"),
)
first_name = models.CharField(
max_length=30, verbose_name=_("first name"),
)
last_name = models.CharField(
max_length=30, verbose_name=_("last name"),
)
is_staff = models.BooleanField(
verbose_name=_("staff status"),
default=False,

https://riptutorial.com/it/home 76
help_text=_(
"Designates whether the user can log into this admin site."
),
)
is_active = models.BooleanField(
verbose_name=_("active"),
default=True,
help_text=_(
"Designates whether this user should be treated as active. "
"Unselect this instead of deleting accounts."
),
)
date_joined = models.DateTimeField(
verbose_name=_("date joined"), default=timezone.now,
)

objects = UserManager()

Estendi facilmente il modello utente di Django

La nostra classe UserProfile

Creare una classe di modello UserProfile con la relazione di OneToOne sul modello User predefinito:

from django.db import models


from django.contrib.auth.models import User
from django.db.models.signals import post_save

class UserProfile(models.Model):
user = models.OneToOneField(User, related_name='user')
photo = FileField(verbose_name=_("Profile Picture"),
upload_to=upload_to("main.UserProfile.photo", "profiles"),
format="Image", max_length=255, null=True, blank=True)
website = models.URLField(default='', blank=True)
bio = models.TextField(default='', blank=True)
phone = models.CharField(max_length=20, blank=True, default='')
city = models.CharField(max_length=100, default='', blank=True)
country = models.CharField(max_length=100, default='', blank=True)
organization = models.CharField(max_length=100, default='', blank=True)

Segnali Django al lavoro

Usando i Segnali Django, crea un nuovo UserProfile User immediatamente viene creato un
oggetto User . Questa funzione può essere nascosta sotto la classe del modello UserProfile nello
stesso file o posizionarla dove preferisci. Non m'importa, finché lo fai correttamente.

def create_profile(sender, **kwargs):


user = kwargs["instance"]
if kwargs["created"]:
user_profile = UserProfile(user=user)
user_profile.save()
post_save.connect(create_profile, sender=User)

inlineformset_factory al salvataggio

https://riptutorial.com/it/home 77
Ora per your views.py , potresti avere qualcosa di simile a questo:

from django.shortcuts import render, HttpResponseRedirect


from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from .models import UserProfile
from .forms import UserForm
from django.forms.models import inlineformset_factory
from django.core.exceptions import PermissionDenied
@login_required() # only logged in users should access this
def edit_user(request, pk):
# querying the User object with pk from url
user = User.objects.get(pk=pk)

# prepopulate UserProfileForm with retrieved user values from above.


user_form = UserForm(instance=user)

# The sorcery begins from here, see explanation https://blog.khophi.co/extending-django-


user-model-userprofile-like-a-pro/
ProfileInlineFormset = inlineformset_factory(User, UserProfile, fields=('website', 'bio',
'phone', 'city', 'country', 'organization'))
formset = ProfileInlineFormset(instance=user)

if request.user.is_authenticated() and request.user.id == user.id:


if request.method == "POST":
user_form = UserForm(request.POST, request.FILES, instance=user)
formset = ProfileInlineFormset(request.POST, request.FILES, instance=user)

if user_form.is_valid():
created_user = user_form.save(commit=False)
formset = ProfileInlineFormset(request.POST, request.FILES,
instance=created_user)

if formset.is_valid():
created_user.save()
formset.save()
return HttpResponseRedirect('/accounts/profile/')

return render(request, "account/account_update.html", {


"noodle": pk,
"noodle_form": user_form,
"formset": formset,
})
else:
raise PermissionDenied

Il nostro modello

Quindi sputa tutto al tuo modello account_update.html in questo modo:

{% load material_form %}
<!-- Material form is just a materialize thing for django forms -->
<div class="col s12 m8 offset-m2">
<div class="card">
<div class="card-content">
<h2 class="flow-text">Update your information</h2>
<form action="." method="POST" class="padding">
{% csrf_token %} {{ noodle_form.as_p }}
<div class="divider"></div>

https://riptutorial.com/it/home 78
{{ formset.management_form }}
{{ formset.as_p }}
<button type="submit" class="btn-floating btn-large waves-light waves-effect"><i
class="large material-icons">done</i></button>
<a href="#" onclick="window.history.back(); return false;" title="Cancel"
class="btn-floating waves-effect waves-light red"><i class="material-icons">history</i></a>

</form>
</div>
</div>
</div>

Sopra lo snippet tratto dall'estensione di Django UserProfile come un Pro

Specificare un modello utente personalizzato

Il modello User incorporato di Django non è sempre appropriato per alcuni tipi di progetti. Su alcuni
siti potrebbe essere più logico utilizzare un indirizzo email al posto di un nome utente, ad esempio.

Puoi sostituire il modello User predefinito aggiungendo il modello User personalizzato


all'impostazione AUTH_USER_MODEL nel file delle impostazioni del progetto:

AUTH_USER_MODEL = 'myapp.MyUser'

Tieni presente che è altamente consigliato creare il AUTH_USER_MODEL prima di creare qualsiasi
migrazione o eseguire manage.py migrate per la prima volta. A causa delle limitazioni della funzione
di dipendenza da synamic di Django.

Ad esempio sul tuo blog potresti volere che altri autori siano in grado di accedere con un indirizzo
email invece del normale nome utente, quindi creiamo un modello User personalizzato con un
indirizzo email come USERNAME_FIELD :

from django.contrib.auth.models import AbstractBaseUser

class CustomUser(AbstractBaseUser):
email = models.EmailField(unique=True)

USERNAME_FIELD = 'email'

Con l'ereditarietà di AbstractBaseUser possiamo costruire un modello User conforme.


AbstractBaseUser fornisce l'implementazione di base di un modello User .

Per consentire a Django manage.py createsuperuser comando di un utente, sapere quali altri campi
sono richiesti, possiamo specificare un REQUIRED_FIELDS . Questo valore non ha alcun effetto in altre
parti di Django!

class CustomUser(AbstractBaseUser):
...
first_name = models.CharField(max_length=254)
last_name = models.CharField(max_length=254)
...
REQUIRED_FIELDS = ['first_name', 'last_name']

https://riptutorial.com/it/home 79
Per essere compatibili con l'altra parte di Django dobbiamo ancora specificare il valore is_active ,
le funzioni get_full_name() e get_short_name() :

class CustomUser(AbstractBaseUser):
...
is_active = models.BooleanField(default=False)
...
def get_full_name(self):
full_name = "{0} {1}".format(self.first_name, self.last_name)
return full_name.strip()

def get_short_name(self):
return self.first_name

Dovresti anche creare un UserManager personalizzato per il tuo modello User , che consente a
Django di utilizzare le create_user() e create_superuser() :

from django.contrib.auth.models import BaseUserManager

class CustomUserManager(BaseUserManager):
def create_user(self, email, first_name, last_name, password=None):
if not email:
raise ValueError('Users must have an email address')

user = self.model(
email=self.normalize_email(email),
)

user.set_password(password)
user.first_name = first_name
user.last_name = last_name
user.save(using=self._db)
return user

def create_superuser(self, email, first_name, last_name, password):


user = self.create_user(
email=email,
first_name=first_name,
last_name=last_name,
password=password,
)

user.is_admin = True
user.is_active = True
user.save(using=self.db)
return user

Fare riferimento al modello utente

Il tuo codice non funzionerà nei progetti in cui fai riferimento al modello User ( e dove è stata
modificata l'impostazione AUTH_USER_MODEL ) direttamente.

Ad esempio: se si desidera creare un modello Post per un blog con un modello User
personalizzato, è necessario specificare il modello User personalizzato in questo modo:

https://riptutorial.com/it/home 80
from django.conf import settings
from django.db import models

class Post(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

Leggi Estensione o sostituzione del modello utente online:


https://riptutorial.com/it/django/topic/1209/estensione-o-sostituzione-del-modello-utente

https://riptutorial.com/it/home 81
Capitolo 21: F () espressioni
introduzione
Un'espressione F () è un modo per Django di utilizzare un oggetto Python per fare riferimento al
valore del campo del modello o della colonna annotata nel database senza dover inserire il valore
nella memoria di Python. Ciò consente agli sviluppatori di evitare determinate condizioni di gara e
di filtrare i risultati in base ai valori del campo del modello.

Sintassi
• da django.db.models import F

Examples
Evitare le condizioni di gara

Vedi questa domanda Q & A se non sai quali sono le condizioni di gara.

Il seguente codice può essere soggetto a condizioni di gara:

article = Article.objects.get(pk=69)
article.views_count += 1
article.save()

Se views_count è uguale a 1337 , ciò comporterà una query di questo tipo:

UPDATE app_article SET views_count = 1338 WHERE id=69

Se due client accedono contemporaneamente a questo articolo, ciò che potrebbe accadere è che
la seconda richiesta HTTP esegua Article.objects.get(pk=69) prima che il primo esegua
article.save() . Pertanto, entrambe le richieste avranno views_count = 1337 , incrementarlo e
salvare views_count = 1338 nel database, mentre in realtà dovrebbe essere 1339 .

Per risolvere questo problema, usa un'espressione F() :

article = Article.objects.get(pk=69)
article.views_count = F('views_count') + 1
article.save()

Questo, d'altra parte, si tradurrà in tale query:

UPDATE app_article SET views_count = views_count + 1 WHERE id=69

Aggiornamento di queryset in blocco

https://riptutorial.com/it/home 82
Supponiamo di voler rimuovere 2 upvotes da tutti gli articoli dell'autore con id 51 .
Farlo solo con Python eseguirà N query ( N è il numero di articoli nel queryset):

for article in Article.objects.filter(author_id=51):


article.upvotes -= 2
article.save()
# Note that there is a race condition here but this is not the focus
# of this example.

Cosa succede se invece di trascinare tutti gli articoli in Python, passandoci sopra, diminuendo gli
upvotes e salvando ogni aggiornato nel database, c'era un altro modo?
Usando un'espressione F() , puoi farlo in una query:

Article.objects.filter(author_id=51).update(upvotes=F('upvotes') - 2)

Quale può essere tradotto nella seguente query SQL:

UPDATE app_article SET upvotes = upvotes - 2 WHERE author_id = 51

Perché è meglio?

• Invece di fare il lavoro in Python, passiamo il carico nel database che è messo a punto per
fare queste domande.
• Riduce efficacemente il numero di query del database necessarie per ottenere il risultato
desiderato.

Esegui operazioni aritmetiche tra i campi

F()espressioni F() possono essere utilizzate per eseguire operazioni aritmetiche ( + , - , * ecc.)
Tra i campi del modello, al fine di definire una ricerca / connessione algebrica tra di esse.

• Lascia che il modello sia:

class MyModel(models.Model):
int_1 = models.IntegerField()
int_2 = models.IntegerField()

• Ora lascia supporre che vogliamo recuperare tutti gli oggetti di MyModel tabella che di int_1 e
int_2 campi soddisfano questa equazione: int_1 + int_2 >= 5 . Utilizzando annotate() e
filter() otteniamo:

result = MyModel.objects.annotate(
diff=F(int_1) + F(int_2)
).filter(diff__gte=5)

result ora contiene tutti gli oggetti di cui sopra.

Sebbene l'esempio utilizzi i campi Integer , questo metodo funzionerà su ogni campo in cui è
possibile applicare un'operazione aritmetica.

https://riptutorial.com/it/home 83
Leggi F () espressioni online: https://riptutorial.com/it/django/topic/2765/f----espressioni

https://riptutorial.com/it/home 84
Capitolo 22: formsets
Sintassi
• NewFormSet = formset_factory (SomeForm, extra = 2)
• formset = NewFormSet (initial = [{'some_field': 'Field Value', 'other_field': 'Other Field
Value',}]))

Examples
Formset con dati inizializzati e unitializzati

Formset è un modo per rendere più moduli in una pagina, come una griglia di dati. Es: Questo
ChoiceForm potrebbe essere associato a qualche domanda di ordinamento. come, i bambini sono
più intelligenti tra quale età?

appname/forms.py

from django import forms


class ChoiceForm(forms.Form):
choice = forms.CharField()
pub_date = forms.DateField()

Nel vostro punto di vista è possibile utilizzare formset_factory costruttore che prende prende Form
come parametro la sua ChoiceForm in questo caso e extra che descrive quante forme aggiuntivi
diverso inizializzati form / moduli deve essere reso, e si può ciclo sopra il formset oggetto come
qualsiasi altro iterabile.

Se il formset non è inizializzato con i dati, stampa il numero di moduli uguale a extra + 1 e se il
formset è inizializzato, stampa initialized + extra caso di numero extra di moduli vuoti diversi da
quelli inizializzati.

appname/views.py

import datetime
from django.forms import formset_factory
from appname.forms import ChoiceForm
ChoiceFormSet = formset_factory(ChoiceForm, extra=2)
formset = ChoiceFormSet(initial=[
{'choice': 'Between 5-15 ?',
'pub_date': datetime.date.today(),}
])

se si esegue il loop su un formset object come questo per form in formset: print (form.as_table ())

Output in rendered template

<tr>
<th><label for="id_form-0-choice">Choice:</label></th>

https://riptutorial.com/it/home 85
<td><input type="text" name="form-0-choice" value="Between 5-15 ?" id="id_form-0-choice"
/></td>
</tr>
<tr>
<th><label for="id_form-0-pub_date">Pub date:</label></th>
<td><input type="text" name="form-0-pub_date" value="2008-05-12" id="id_form-0-pub_date"
/></td>
</tr>
<tr>
<th><label for="id_form-1-choice">Choice:</label></th>
<td><input type="text" name="form-1-choice" id="id_form-1-choice" /></td>
</tr>
<tr>
<th><label for="id_form-1-pub_date">Pub date:</label></th>
<td><input type="text" name="form-1-pub_date" id="id_form-1-pub_date" /></td
</tr>
<tr>
<th><label for="id_form-2-choice">Choice:</label></th>
<td><input type="text" name="form-2-choice" id="id_form-2-choice" /></td>
</tr>
<tr>
<th><label for="id_form-2-pub_date">Pub date:</label></th>
<td><input type="text" name="form-2-pub_date" id="id_form-2-pub_date" /></td>
</tr>

Leggi formsets online: https://riptutorial.com/it/django/topic/6082/formsets

https://riptutorial.com/it/home 86
Capitolo 23: Fusi orari
introduzione
I fusi orari sono spesso una seccatura per gli sviluppatori. Django offre alcune ottime utility a tua
disposizione per rendere i fusi orari facili da usare.

Anche se il tuo progetto funziona in un singolo fuso orario, è comunque buona norma archiviare i
dati come UTC nel tuo database per gestire i casi di ora legale. Se si opera su più fusi orari, la
memorizzazione dei dati temporali come UTC è indispensabile.

Examples
Abilita supporto fuso orario

Per prima cosa, assicurati che USE_TZ = True nel file settings.py . Imposta anche un valore
predefinito del fuso orario su TIME_ZONE come TIME_ZONE='UTC' . Visualizza l'elenco completo dei fusi
orari qui .

Se USE_TZ è False, TIME_ZONE sarà il fuso orario che Django utilizzerà per memorizzare tutti i dati.
Quando USE_TZ è abilitato, TIME_ZONE è il fuso orario predefinito che Django utilizzerà per
visualizzare i datetimes nei modelli e per interpretare i dati di data immessi nei moduli.

Con il supporto fuso orario abilitato, django memorizzerà i dati datetime nel database come il fuso
orario UTC

Impostazione dei fusi orari della sessione

Gli oggetti datetime.datetime di Python hanno un attributo tzinfo che viene utilizzato per
memorizzare le informazioni sul fuso orario. Quando l'attributo è impostato, l'oggetto è considerato
Aware, quando l'attributo non è impostato è considerato un Naive.

Per garantire che un fuso orario sia ingenuo o consapevole, puoi utilizzare .is_naive() e
.is_aware()

Se avete USE_TZ abilitati nel tuo settings.py file, un datetime avrà informazioni sul fuso orario
collegato ad esso fino a quando il difetto TIME_ZONE si trova in settings.py

Sebbene questo fuso orario predefinito possa essere buono in alcuni casi, probabilmente non è
sufficiente, soprattutto se si gestiscono utenti in più fusi orari. Per ottenere ciò, è necessario
utilizzare il middleware.

import pytz

from django.utils import timezone

# make sure you add `TimezoneMiddleware` appropriately in settings.py

https://riptutorial.com/it/home 87
class TimezoneMiddleware(object):
"""
Middleware to properly handle the users timezone
"""

def __init__(self, get_response):


self.get_response = get_response

def __call__(self, request):


# make sure they are authenticated so we know we have their tz info.
if request.user.is_authenticated():
# we are getting the users timezone that in this case is stored in
# a user's profile
tz_str = request.user.profile.timezone
timezone.activate(pytz.timezone(tz_str))
# otherwise deactivate and the default time zone will be used anyway
else:
timezone.deactivate()

response = self.get_response(request)
return response

Ci sono alcune cose nuove in corso. Per saperne di più sul middleware e su cosa controlla questa
parte della documentazione . In __call__ l'impostazione dei dati del fuso orario. Inizialmente ci
assicuriamo che l'utente sia autenticato, per assicurarci di avere i dati del fuso orario per questo
utente. Quando lo sappiamo, attiviamo il fuso orario per la sessione degli utenti utilizzando
timezone.activate() . Per convertire la stringa del fuso orario abbiamo qualcosa utilizzabile da
datetime, usiamo pytz.timezone(str) .

Ora, quando gli oggetti datetime sono accessibili nei modelli, verranno automaticamente convertiti
dal formato "UTC" del database a qualsiasi fuso orario in cui si trova l'utente. Basta accedere
all'oggetto datetime e il suo fuso orario verrà impostato assumendo che il middleware precedente
sia impostato propriamente.

{{ my_datetime_value }}

Se desideri un controllo a grana fine se viene utilizzato il fuso orario dell'utente, dai un'occhiata a
quanto segue:

{% load tz %}
{% localtime on %}
{# this time will be respect the users time zone #}
{{ your_date_time }}
{% endlocaltime %}

{% localtime off %}
{# this will not respect the users time zone #}
{{ your_date_time }}
{% endlocaltime %}

Nota, questo metodo descritto funziona solo in Django 1.10 e oltre. Per supportare django da
precedente a 1.10, guarda a MiddlewareMixin

Leggi Fusi orari online: https://riptutorial.com/it/django/topic/10566/fusi-orari

https://riptutorial.com/it/home 88
Capitolo 24: Gestori e Queryys personalizzati
Examples
Definire un manager di base usando Querysets e il metodo `as_manager`

Django manger è un'interfaccia attraverso la quale il modello django interroga il database. Il


campo degli objects usato nella maggior parte delle query di django è in realtà il gestore
predefinito creato per noi da django (questo viene creato solo se non definiamo i gestori
personalizzati).

Perché dovremmo definire un gestore personalizzato / queryset?

Per evitare di scrivere query comuni su tutto il nostro codebase e invece di riferirle usando
un'astrazione più facile da ricordare. Esempio: decidi tu stesso quale versione è più leggibile:

• Ottieni solo tutti gli utenti attivi: User.objects.filter(is_active=True) vs User.manager.active()


• Ottieni tutti i dermatologi attivi sulla nostra piattaforma:
User.objects.filter(is_active=True).filter(is_doctor=True).filter(specialization='Dermatology')
vs User.manager.doctors.with_specialization('Dermatology')

Un altro vantaggio è che se domani decidiamo che tutti gli psychologists sono anche
dermatologists , possiamo facilmente modificare la query nel nostro manager e farla finita.

Di seguito è riportato un esempio di creazione di un Manager personalizzato definito creando un


QuerySet e utilizzando il metodo as_manager .

from django.db.models.query import QuerySet

class ProfileQuerySet(QuerySet):
def doctors(self):
return self.filter(user_type="Doctor", user__is_active=True)

def with_specializations(self, specialization):


return self.filter(specializations=specialization)

def users(self):
return self.filter(user_type="Customer", user__is_active=True)

ProfileManager = ProfileQuerySet.as_manager

Lo aggiungeremo al nostro modello come di seguito:

class Profile(models.Model):
...
manager = ProfileManager()

NOTA : una volta definito un manager sul nostro modello, gli objects non saranno più definiti per il
modello.

https://riptutorial.com/it/home 89
select_related per tutte le query

Modello con ForeignKey

Lavoreremo con questi modelli:

from django.db import models

class Book(models.Model):
name= models.CharField(max_length=50)
author = models.ForeignKey(Author)

class Author(models.Model):
name = models.CharField(max_length=50)

Supponiamo di accedere (sempre) spesso a book.author.name

In vista

Potremmo usare quanto segue, ogni volta,

books = Book.objects.select_related('author').all()

Ma questo non è SECCO.

Manager personalizzato

class BookManager(models.Manager):

def get_queryset(self):
qs = super().get_queryset()
return qs.select_related('author')

class Book(models.Model):
...
objects = BookManager()

Nota : la chiamata a super deve essere cambiata per python 2.x

Ora tutto ciò che dobbiamo usare nelle viste è

books = Book.objects.all()

e nessuna query aggiuntiva sarà effettuata in template / view.

Definisci gestori personalizzati

Molto spesso capita di trattare con modelli che hanno qualcosa come un campo published . Questi
tipi di campi sono quasi sempre usati per recuperare oggetti, così ti troverai a scrivere qualcosa
come:

https://riptutorial.com/it/home 90
my_news = News.objects.filter(published=True)

troppe volte. Puoi utilizzare i gestori personalizzati per gestire queste situazioni, in modo che tu
possa scrivere qualcosa come:

my_news = News.objects.published()

che è più bello e più facile da leggere anche da altri sviluppatori.

Creare un file managers.py nella directory app, e definire una nuova models.Manager classe:

from django.db import models

class NewsManager(models.Manager):

def published(self, **kwargs):


# the method accepts **kwargs, so that it is possible to filter
# published news
# i.e: News.objects.published(insertion_date__gte=datetime.now)
return self.filter(published=True, **kwargs)

usa questa classe ridefinendo la proprietà objects nella classe model:

from django.db import models

# import the created manager


from .managers import NewsManager

class News(models.Model):
""" News model
"""
insertion_date = models.DateTimeField('insertion date', auto_now_add=True)
title = models.CharField('title', max_length=255)
# some other fields here
published = models.BooleanField('published')

# assign the manager class to the objects property


objects = NewsManager()

Ora puoi ottenere le tue notizie pubblicate in questo modo:

my_news = News.objects.published()

e puoi anche eseguire più filtri:

my_news = News.objects.published(title__icontains='meow')

Leggi Gestori e Queryys personalizzati online: https://riptutorial.com/it/django/topic/1400/gestori-e-


queryys-personalizzati

https://riptutorial.com/it/home 91
Capitolo 25: impostazioni
Examples
Impostazione del fuso orario

Puoi impostare il fuso orario che verrà utilizzato da Django nel file settings.py . Esempi:

TIME_ZONE = 'UTC' # use this, whenever possible


TIME_ZONE = 'Europe/Berlin'
TIME_ZONE = 'Etc/GMT+1'

Ecco l'elenco dei fusi orari validi

Quando si esegue in un ambiente Windows , questo deve essere impostato allo stesso fuso
orario del sistema .

Se non vuoi che Django utilizzi dati datati con timezone:

USE_TZ = False

Le best practice di Django richiedono l'uso di UTC per l'archiviazione delle informazioni nel
database:

Anche se il tuo sito web è disponibile in un unico fuso orario, è comunque buona
norma memorizzare i dati in UTC nel tuo database. Il motivo principale è Daylight
Saving Time (DST). Molti paesi hanno un sistema di DST, in cui gli orologi vengono
spostati in avanti in primavera e indietro in autunno. Se lavori in ora locale, è probabile
che tu incontri errori due volte l'anno, quando le transizioni avvengono.

https://docs.djangoproject.com/en/stable/topics/i18n/timezones/

Accesso alle impostazioni

Una volta che hai tutte le impostazioni, vorrai usarle nel tuo codice. Per fare ciò, aggiungi la
seguente importazione al tuo file:

from django.conf import settings

È quindi possibile accedere alle proprie impostazioni come attributi del modulo delle settings , ad
esempio:

if not settings.DEBUG:
email_user(user, message)

Utilizzo di BASE_DIR per garantire la portabilità delle app

https://riptutorial.com/it/home 92
È una cattiva idea di percorsi di codice complessi nella tua applicazione. Uno dovrebbe sempre
usare url relativi in modo che il codice possa funzionare senza problemi su macchine diverse. Il
modo migliore per configurarlo è definire una variabile come questa

import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))

Quindi utilizzare questa variabile BASE_DIR per definire tutte le altre impostazioni.

TEMPLATE_PATH = os.path.join(BASE_DIR, "templates")


STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),

E così via. Ciò garantisce che puoi trasferire il tuo codice su macchine diverse senza
preoccupazioni.

Tuttavia, os.path è un po ' os.path . Ad esempio se il tuo modulo delle impostazioni è


project.settings.dev , dovrai scrivere:

BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))

Un'alternativa è usare il modulo unipath (che puoi installare con pip install unipath ).

from unipath import Path

BASE_DIR = Path(__file__).ancestor(2) # or ancestor(3) if using a submodule

TEMPLATE_PATH = BASE_DIR.child('templates')
STATICFILES_DIRS = [
BASE_DIR.child('static'),
]

Utilizzo delle variabili di ambiente per gestire le impostazioni tra i server

L'utilizzo delle variabili d'ambiente è un modo ampiamente utilizzato per impostare la


configurazione di un'app in base all'ambiente, come indicato nell'app Twelve-Factor .

Poiché è probabile che le configurazioni cambino tra gli ambienti di distribuzione, questo è un
modo molto interessante per modificare la configurazione senza dover scavare nel codice
sorgente dell'app, oltre a tenere segreti al di fuori dei file dell'applicazione e del repository del
codice sorgente.

In Django, le impostazioni principali si trovano come settings.py nella cartella del tuo progetto.
Poiché si tratta di un semplice file Python, è possibile utilizzare il modulo os di Python dalla libreria
standard per accedere all'ambiente (e persino avere i valori predefiniti appropriati).

settings.py

https://riptutorial.com/it/home 93
import os

SECRET_KEY = os.environ.get('APP_SECRET_KEY', 'unsafe-secret-key')

DEBUG = bool(os.environ.get('DJANGO_DEBUG', True) == 'False')

ALLOWED_HOSTS = os.environ.get('DJANGO_ALLOWED_HOSTS', '').split()

DATABASES = {
'default': {
'ENGINE': os.environ.get('APP_DB_ENGINE', 'django.db.backends.sqlite3'),
'NAME': os.environ.get('DB_NAME', 'db.sqlite'),
'USER': os.environ.get('DB_USER', ''),
'PASSWORD': os.environ.get('DB_PASSWORD', ''),
'HOST': os.environ.get('DB_HOST', None),
'PORT': os.environ.get('DB_PORT', None),
'CONN_MAX_AGE': 600,
}
}

Con Django puoi cambiare la tua tecnologia di database, in modo che tu possa usare sqlite3 sul
tuo computer di sviluppo (e questo dovrebbe essere un predefinito corretto per il commit su un
sistema di controllo del codice sorgente). Anche se questo è possibile, non è consigliabile:

I servizi di supporto, come il database dell'applicazione, il sistema di accodamento o la


cache, sono un'area in cui la parità di sviluppo / sviluppo è importante. ( L'app Twelve-
Factor - Dev / prod parity )

Per utilizzare un parametro DATABASE_URL per la connessione al database, si prega di dare


un'occhiata all'esempio correlato .

Utilizzando più impostazioni

Il layout di progetto predefinito di Django crea un singolo settings.py . Questo è spesso utile per
dividerlo in questo modo:

myprojectroot/
myproject/
__init__.py
settings/
__init__.py
base.py
dev.py
prod.py
tests.py

Ciò consente di lavorare con impostazioni diverse a seconda che si tratti di sviluppo, produzione,
test o altro.

Quando si passa dal layout predefinito a questo layout, il settings.py originale diventa
settings/base.py Quando ogni altro sottomodulo eseguirà una "sottoclasse" di settings/base.py
iniziando from .base import * . Ad esempio, ecco come possono essere le settings/dev.py :

https://riptutorial.com/it/home 94
# -*- coding: utf-8 -*-
from .base import * # noqa

DEBUG = True
INSTALLED_APPS.extend([
'debug_toolbar',
])
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
INTERNAL_IPS = ['192.168.0.51', '192.168.0.69']

# 1 alternativo
Perché i comandi di django-admin funzionino correttamente, devi impostare la variabile di ambiente
DJANGO_SETTINGS_MODULE (che di default è myproject.settings ). In fase di sviluppo, lo imposterai su
myproject.settings.dev . In produzione, lo imposterai su myproject.settings.prod . Se si utilizza un
virtualenv, è meglio impostarlo nello script postactivate :

#!/bin/sh
export PYTHONPATH="/home/me/django_projects/myproject:$VIRTUAL_ENV/lib/python3.4"
export DJANGO_SETTINGS_MODULE="myproject.settings.dev"

Se si desidera utilizzare un modulo delle impostazioni che non viene indirizzato da


DJANGO_SETTINGS_MODULE per una volta, è possibile utilizzare l'opzione --settings di django-admin :

django-admin test --settings=myproject.settings.tests

N. 2 alternativo
Se si desidera lasciare DJANGO_SETTINGS_MODULE alla sua configurazione predefinita (
myproject.settings ), è sufficiente indicare al modulo delle settings configurazione da caricare
inserendo l'importazione nel file __init__.py .

Nell'esempio sopra, lo stesso risultato potrebbe essere ottenuto avendo un __init__.py impostato
su:

from .dev import *

Utilizzo di più file di requisiti

Ogni file di requisiti deve corrispondere al nome di un file di impostazioni. Leggi Utilizzo di più
impostazioni per ulteriori informazioni.

Struttura
djangoproject

https://riptutorial.com/it/home 95
├── config
│ ├── __init__.py
│ ├── requirements
│ │ ├── base.txt
│ │ ├── dev.txt
│ │ ├── test.txt
│ │ └── prod.txt
│ └── settings
└── manage.py

Nel file base.txt , posiziona le dipendenze utilizzate in tutti gli ambienti.

# base.txt
Django==1.8.0
psycopg2==2.6.1
jinja2==2.8

E in tutti gli altri file, includere le dipendenze di base con -r base.txt e aggiungere specifiche
dipendenze necessarie per l'ambiente corrente.

# dev.txt
-r base.txt # includes all dependencies in `base.txt`

# specific dependencies only used in dev env


django-queryinspect==0.1.0

# test.txt
-r base.txt # includes all dependencies in `base.txt`

# specific dependencies only used in test env


nose==1.3.7
django-nose==1.4

# prod.txt
-r base.txt # includes all dependencies in `base.txt`

# specific dependencies only used in production env


django-queryinspect==0.1.0
gunicorn==19.3.0
django-storages-redux==1.3
boto==2.38.0

Infine, per installare le dipendenze. Esempio, su dev env: pip install -r


config/requirements/dev.txt

Nascondere i dati segreti utilizzando un file JSON

Quando si utilizza un VCS come Git o SVN, ci sono alcuni dati segreti che non devono mai essere
sottoposti a versionamento (se il repository è pubblico o privato).

Tra questi dati, si trova l'impostazione SECRET_KEY e la password del database.

Una pratica comune per nascondere queste impostazioni dal controllo di versione è creare un file
secrets.json alla radice del progetto ( grazie a " Two Scoops of Django " per l'idea ):

https://riptutorial.com/it/home 96
{
"SECRET_KEY": "N4HE:AMk:.Ader5354DR453TH8SHTQr",
"DB_PASSWORD": "v3ry53cr3t"
}

E aggiungilo alla tua lista di cose da ignorare ( .gitignore per git):

*.py[co]
*.sw[po]
*~
/secrets.json

Quindi aggiungere la seguente funzione al modulo delle settings :

import json
import os
from django.core.exceptions import ImproperlyConfigured

with open(os.path.join(BASE_DIR, 'secrets.json')) as secrets_file:


secrets = json.load(secrets_file)

def get_secret(setting, secrets=secrets):


"""Get secret setting or fail with ImproperlyConfigured"""
try:
return secrets[setting]
except KeyError:
raise ImproperlyConfigured("Set the {} setting".format(setting))

Quindi riempi le impostazioni in questo modo:

SECRET_KEY = get_secret('SECRET_KEY')
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgres',
'NAME': 'db_name',
'USER': 'username',
'PASSWORD': get_secret('DB_PASSWORD'),
},
}

Crediti: Two Scoops of Django: Best Practices per Django 1.8, di Daniel Roy Greenfeld e Audrey
RoyGreenfeld. Copyright 2015 Two Scoops Press (ISBN 978-0981467344)

Utilizzo di DATABASE_URL dall'ambiente

Nei siti PaaS come Heroku, è normale ricevere le informazioni del database come una singola
variabile di ambiente URL, invece di diversi parametri (host, porta, utente, password ...).

Esiste un modulo, dj_database_url che estrae automaticamente la variabile d'ambiente


DATABASE_URL in un dizionario Python appropriato per l'iniezione delle impostazioni del
database in Django.

Uso:

https://riptutorial.com/it/home 97
import dj_database_url

if os.environ.get('DATABASE_URL'):
DATABASES['default'] =
dj_database_url.config(default=os.environ['DATABASE_URL'])

Leggi impostazioni online: https://riptutorial.com/it/django/topic/942/impostazioni

https://riptutorial.com/it/home 98
Capitolo 26: Integrazione continua con
Jenkins
Examples
Script Pipeline di Jenkins 2.0+

Le versioni moderne di Jenkins (versione 2.x) sono dotate di un "Build Pipeline Plugin" che può
essere utilizzato per orchestrare attività CI complesse senza creare una moltitudine di lavori
interconnessi e consentire di controllare facilmente la configurazione di build / test.

È possibile installarlo manualmente in un lavoro di tipo "Pipeline" o, se il progetto è ospitato su


Github, è possibile utilizzare il "Plugin di cartelle dell'organizzazione GitHub" per impostare
automaticamente i lavori per conto dell'utente.

Ecco una semplice configurazione per i siti Django che richiedono l'installazione solo dei moduli
python specificati del sito.

#!/usr/bin/groovy

node {
// If you are having issues with your project not getting updated,
// try uncommenting the following lines.
//stage 'Checkout'
//checkout scm
//sh 'git submodule update --init --recursive'

stage 'Update Python Modules'


// Create a virtualenv in this folder, and install or upgrade packages
// specified in requirements.txt; https://pip.readthedocs.io/en/1.1/requirements.html
sh 'virtualenv env && source env/bin/activate && pip install --upgrade -r requirements.txt'

stage 'Test'
// Invoke Django's tests
sh 'source env/bin/activate && python ./manage.py runtests'
}

Script Pipeline Jenkins 2.0+, contenitori Docker

Ecco un esempio di uno script della pipeline che crea un contenitore Docker, quindi esegue i test
al suo interno. Si presuppone che il punto di accesso sia manage.py o invoke / fabric con un
comando runtests disponibile.

#!/usr/bin/groovy

node {
stage 'Checkout'
checkout scm
sh 'git submodule update --init --recursive'

https://riptutorial.com/it/home 99
imageName = 'mycontainer:build'
remotes = [
'dockerhub-account',
]

stage 'Build'
def djangoImage = docker.build imageName

stage 'Run Tests'


djangoImage.run('', 'runtests')

stage 'Push'
for (int i = 0; i < remotes.size(); i++) {
sh "docker tag ${imageName} ${remotes[i]}/${imageName}"
sh "docker push ${remotes[i]}/${imageName}"
}
}

Leggi Integrazione continua con Jenkins online:


https://riptutorial.com/it/django/topic/5873/integrazione-continua-con-jenkins

https://riptutorial.com/it/home 100
Capitolo 27: Internazionalizzazione
Sintassi
• gettext (messaggio)
• ngettext (singolare, plurale, numero)
• ugettext (messaggio)
• ungettext (singolare, plurale, numero)
• pgettext (contesto, messaggio)
• npgettext (context, singular, plural, number)
• gettext_lazy (messaggio)
• ngettext_lazy (singolare, plurale, numero = Nessuno)
• ugettext_lazy (messaggio)
• ungettext_lazy (singular, plural, number = None)
• pgettext_lazy (contesto, messaggio)
• npgettext_lazy (context, singular, plural, number = None)
• gettext_noop (messaggio)
• ugettext_noop (messaggio)

Examples
Introduzione all'internazionalizzazione

Impostare
settings.py

from django.utils.translation import ugettext_lazy as _

USE_I18N = True # Enable Internationalization


LANGUAGE_CODE = 'en' # Language in which original texts are written
LANGUAGES = [ # Available languages
('en', _("English")),
('de', _("German")),
('fr', _("French")),
]

# Make sure the LocaleMiddleware is included, AFTER SessionMiddleware


# and BEFORE middlewares using internationalization (such as CommonMiddleware)
MIDDLEWARE_CLASSES = [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
]

https://riptutorial.com/it/home 101
Marcare le stringhe come traducibili
Il primo passo nella traduzione è contrassegnare le stringhe come traducibili . Questo li sta
passando attraverso una delle funzioni gettext (vedi la sezione Sintassi ). Ad esempio, ecco un
esempio di definizione del modello:

from django.utils.translation import ugettext_lazy as _


# It is common to import gettext as the shortcut `_` as it is often used
# several times in the same file.

class Child(models.Model):

class Meta:
verbose_name = _("child")
verbose_name_plural = _("children")

first_name = models.CharField(max_length=30, verbose_name=_("first name"))


last_name = models.CharField(max_length=30, verbose_name=_("last name"))
age = models.PositiveSmallIntegerField(verbose_name=_("age"))

Tutte le stringhe incapsulate in _() ora sono contrassegnate come traducibili. Quando vengono
stampati, saranno sempre visualizzati come stringa incapsulata, qualunque sia la lingua scelta
(poiché non è ancora disponibile la traduzione).

Tradurre le stringhe
Questo esempio è sufficiente per iniziare con la traduzione. La maggior parte delle volte vorrai
solo contrassegnare le stringhe come traducibili per anticipare la futura internazionalizzazione
del tuo progetto. Quindi, questo è coperto in un altro esempio .

Traduzione Lazy vs Non-Lazy

Quando si utilizza la traduzione non-pigra, le stringhe vengono tradotte immediatamente.

>>> from django.utils.translation import activate, ugettext as _


>>> month = _("June")
>>> month
'June'
>>> activate('fr')
>>> _("June")
'juin'
>>> activate('de')
>>> _("June")
'Juni'
>>> month
'June'

Quando si utilizza la pigrizia, la traduzione si verifica solo quando effettivamente utilizzata.

>>> from django.utils.translation import activate, ugettext_lazy as _

https://riptutorial.com/it/home 102
>>> month = _("June")
>>> month
<django.utils.functional.lazy.<locals>.__proxy__ object at 0x7f61cb805780>
>>> str(month)
'June'
>>> activate('fr')
>>> month
<django.utils.functional.lazy.<locals>.__proxy__ object at 0x7f61cb805780>
>>> "month: {}".format(month)
'month: juin'
>>> "month: %s" % month
'month: Juni'

Devi usare la traduzione lazy nei casi in cui:

• La traduzione non può essere attivata (lingua non selezionata) quando viene valutato
_("some string")
• Alcune stringhe possono essere valutate solo all'avvio (ad esempio in attributi di classe
come le definizioni dei campi di modello e modulo)

Traduzione in modelli

Per abilitare la traduzione nei modelli è necessario caricare la libreria i18n .

{% load i18n %}

La traduzione di base è fatta con il tag modello trans .

{% trans "Some translatable text" %}


{# equivalent to python `ugettext("Some translatable text")` #}

Il tag del modello trans supporta il contesto:

{% trans "May" context "month" %}


{# equivalent to python `pgettext("May", "month")` #}

Per includere segnaposti nella stringa di traduzione, come in:

_("My name is {first_name} {last_name}").format(first_name="John", last_name="Doe")

Dovrai usare il tag del modello blocktrans :

{% blocktrans with first_name="John" last_name="Doe" %}


My name is {{ first_name }} {{ last_name }}
{% endblocktrans %}

Ovviamente invece di "John" e "Doe" puoi avere variabili e filtri:

{% blocktrans with first_name=user.first_name last_name=user.last_name|title %}


My name is {{ first_name }} {{ last_name }}
{% endblocktrans %}

https://riptutorial.com/it/home 103
Se first_name e last_name sono già nel tuo contesto, puoi persino omettere la clausola with :

{% blocktrans %}My name is {{ first_name }} {{ last_name }}{% endblocktrans %}

Tuttavia, solo le variabili di contesto "di primo livello" possono essere utilizzate. Questo NON
funzionerà:

{% blocktrans %}
My name is {{ user.first_name }} {{ user.last_name }}
{% endblocktrans %}

Ciò è dovuto principalmente al fatto che il nome della variabile viene utilizzato come segnaposto
nei file di traduzione.

Il tag del modello blocktrans accetta anche la pluralizzazione.

{% blocktrans count nb=users|length }}


There is {{ nb }} user.
{% plural %}
There are {{ nb }} users.
{% endblocktrans %}

Infine, indipendentemente dalla libreria i18n , puoi passare stringhe traducibili ai tag modello
usando la sintassi _("") .

{{ site_name|default:_("It works!") }}
{% firstof var1 var2 _("translatable fallback") %}

Questo è un sistema di django template magico incorporato per simulare una sintassi di chiamata
di una funzione, ma questa non è una chiamata di funzione. _("It works!") Passò al tag del
template di default come una stringa '_("It works!")' Che viene poi analizzata una stringa
traducibile, proprio come il name sarebbe analizzato come variabile e il "name" sarebbe analizzato
come una stringa.

Tradurre le stringhe

Per tradurre le stringhe, dovrai creare i file di traduzione. Per fare ciò, django viene fornito con i
comandi di gestione makemessages .

$ django-admin makemessages -l fr
processing locale fr

Il comando precedente scoprirà tutte le stringhe contrassegnate come traducibili all'interno delle
app installate e creerà un file di lingua per ogni app per la traduzione francese. Ad esempio, se si
dispone di una sola app myapp contenente stringhe traducibili, verrà creato un file
myapp/locale/fr/LC_MESSAGES/django.po . Questo file potrebbe essere simile al seguente:

# SOME DESCRIPTIVE TITLE


# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER

https://riptutorial.com/it/home 104
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-07-24 14:01+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: myapp/models.py:22
msgid "user"
msgstr ""

#: myapp/models.py:39
msgid "A user already exists with this email address."
msgstr ""

#: myapp/templates/myapp/register.html:155
#, python-format
msgid ""
"By signing up, you accept our <a href=\"%(terms_url)s\" "
"target=_blank>Terms of services</a>."
msgstr ""

Dovrai prima riempire i segnaposti (sottolineati con le maiuscole). Quindi traduci le stringhe. msgid
è la stringa contrassegnata come traducibile nel tuo codice. msgstr è dove devi scrivere la
traduzione della stringa appena sopra.

Quando una stringa contiene segnaposto, dovrai includerli anche nella tua traduzione. Ad
esempio, tradurrà l'ultimo messaggio come segue:

#: myapp/templates/myapp/register.html:155
#, python-format
msgid ""
"By signing up, you accept our <a href=\"%(terms_url)s\" "
"target=_blank>Terms of services</a>."
msgstr ""
"En vous inscrivant, vous acceptez nos <a href=\"%(terms_url)s\" "
"target=_blank>Conditions d'utilisation</a>"

Una volta completato il file di traduzione, dovrai compilare i file .po in file .mo . Questo viene fatto
chiamando il comando di gestione di compilemessages :

$ django-admin compilemessages

Questo è tutto, ora sono disponibili le traduzioni.

Per aggiornare i file di traduzione quando apporti modifiche al tuo codice, puoi eseguire di nuovo

https://riptutorial.com/it/home 105
django-admin makemessages -l fr . Questo aggiornerà i file .po , mantenendo le tue traduzioni
esistenti e aggiungendone di nuove. Le stringhe eliminate saranno ancora disponibili nei
commenti. Per aggiornare i file .po per tutte le lingue, esegui django-admin makemessages -a . Una
volta aggiornati i file .po , non dimenticare di eseguire nuovamente i django-admin compilemessages
per generare file .mo .

Noop use case

(u)gettext_noop consente di contrassegnare una stringa come traducibile senza effettivamente


tradurla.

Un tipico caso d'uso è quando si desidera registrare un messaggio per gli sviluppatori (in inglese)
ma si desidera anche visualizzarlo sul client (nella lingua richiesta). È possibile passare una
variabile a gettext , ma il suo contenuto non verrà scoperto come stringa traducibile perché
è, per definizione, variabile. .

# THIS WILL NOT WORK AS EXPECTED


import logging
from django.contrib import messages

logger = logging.getLogger(__name__)

error_message = "Oops, something went wrong!"


logger.error(error_message)
messages.error(request, _(error_message))

Il messaggio di errore non apparirà nel file .po e dovrai ricordare che esiste per aggiungerlo
manualmente. Per risolvere questo problema, puoi usare gettext_noop .

error_message = ugettext_noop("Oops, something went wrong!")


logger.error(error_message)
messages.error(request, _(error_message))

Ora la stringa "Oops, something went wrong!" sarà scoperto e disponibile nel file .po quando
generato. E l'errore verrà comunque registrato in inglese per gli sviluppatori.

Insidie comuni

traduzioni sfocate
A volte i makemessages possono pensare che la stringa trovata per la traduzione sia in qualche
modo simile alla traduzione già esistente. Lo farà quando lo contrassegnerà nel file .po con un
commento fuzzy speciale come questo:

#: templates/randa/map.html:91
#, fuzzy
msgid "Country"
msgstr "Länderinfo"

https://riptutorial.com/it/home 106
Anche se la traduzione è corretta o l'hai aggiornata per correggerne una, non verrà utilizzata per
tradurre il tuo progetto se non rimuovi fuzzy riga di commento fuzzy .

Stringhe multilinea
makemessages analizza i file in vari formati, dal semplice testo al codice python e non è progettato
per seguire ogni possibile regola per avere stringhe multi-linea in questi formati. La maggior parte
delle volte funziona perfettamente con le stringhe a linea singola, ma se hai una costruzione come
questa:

translation = _("firstline"
"secondline"
"thirdline")

Raccoglierà solo la prima firstline per la traduzione. La soluzione per questo è evitare l'uso di
stringhe multiline quando possibile.

Leggi Internazionalizzazione online:


https://riptutorial.com/it/django/topic/2579/internazionalizzazione

https://riptutorial.com/it/home 107
Capitolo 28: JSONField - un campo specifico
PostgreSQL
Sintassi
• JSONField (** opzioni)

Osservazioni
• Django's JSONField memorizza i dati in una colonna Postgres JSONB , che è disponibile solo in
Postgres 9.4 e versioni successive.

• JSONField è ottimo quando vuoi uno schema più flessibile. Ad esempio se vuoi cambiare le
chiavi senza dover effettuare alcuna migrazione dei dati, o se non tutti gli oggetti hanno la
stessa struttura.

• Se stai memorizzando i dati con chiavi statiche, considera l'utilizzo di più campi normali
invece di JSONField di JSONField , poiché JSONField interrogazione su JSONField può diventare
piuttosto noiosa.

Concatenare query
Puoi concatenare le query insieme. Ad esempio, se un dizionario esiste all'interno di un elenco,
aggiungere due trattini bassi e la query del dizionario.

Non dimenticare di separare le query con caratteri di sottolineatura doppio.

Examples
Creazione di un campo JSON

Disponibile in Django 1.9+

from django.contrib.postgres.fields import JSONField


from django.db import models

class IceCream(models.Model):
metadata = JSONField()

Puoi aggiungere le normali **options se lo desideri.

! Si noti che è necessario mettere 'django.contrib.postgres' in INSTALLED_APPS nel


vostro settings.py

https://riptutorial.com/it/home 108
Creazione di un oggetto con dati in un campo JSON

Passare i dati in formato Python nativo, ad esempio list , dict , str , None , bool , ecc.

IceCream.objects.create(metadata={
'date': '1/1/2016',
'ordered by': 'Jon Skeet',
'buyer': {
'favorite flavor': 'vanilla',
'known for': ['his rep on SO', 'writing a book']
},
'special requests': ['hot sauce'],
})

Vedere la nota nella sezione "Note" sull'utilizzo di JSONField in pratica.

Interrogazione dei dati di livello superiore

IceCream.objects.filter(metadata__ordered_by='Guido Van Rossum')

Interrogazione dei dati nidificati nei dizionari

Ottieni tutti i coni gelato ordinati dalla gente che ama il cioccolato:

IceCream.objects.filter(metadata__buyer__favorite_flavor='chocolate')

Vedere la nota nella sezione "Note" sulla concatenazione di query.

Interrogare i dati presenti negli array

Un intero sarà interpretato come una ricerca di indice.

IceCream.objects.filter(metadata__buyer__known_for__0='creating stack overflow')

Vedere la nota nella sezione "Note" sulla concatenazione di query.

Ordinamento in base ai valori di JSONField

Ordinare direttamente su JSONField non è ancora supportato in Django. Ma è possibile tramite


RawSQL usando le funzioni di PostgreSQL per jsonb:

from django.db.models.expressions import RawSQL


RatebookDataEntry.objects.all().order_by(RawSQL("data->>%s", ("json_objects_key",)))

Questo esempio ordina per data['json_objects_key'] all'interno JSONField data nome JSONField :

data = JSONField()

https://riptutorial.com/it/home 109
Leggi JSONField - un campo specifico PostgreSQL online:
https://riptutorial.com/it/django/topic/1759/jsonfield---un-campo-specifico-postgresql

https://riptutorial.com/it/home 110
Capitolo 29: Le forme
Examples
Esempio ModelForm

Creare un ModelForm da una classe Model esistente, sottoclasse ModelForm :

from django import forms

class OrderForm(forms.ModelForm):
class Meta:
model = Order
fields = ['item', 'order_date', 'customer', 'status']

Definire una forma di Django da zero (con i widget)

Le forme possono essere definite, in modo simile ai modelli, sottoclassando django.forms.Form .


Sono disponibili varie opzioni di input sul campo, come CharField , URLField , IntegerField , ecc.

Di seguito è riportato un semplice modulo di contatto:

from django import forms

class ContactForm(forms.Form):
contact_name = forms.CharField(
label="Your name", required=True,
widget=forms.TextInput(attrs={'class': 'form-control'}))
contact_email = forms.EmailField(
label="Your Email Address", required=True,
widget=forms.TextInput(attrs={'class': 'form-control'}))
content = forms.CharField(
label="Your Message", required=True,
widget=forms.Textarea(attrs={'class': 'form-control'}))

Widget è la rappresentazione di Django dei tag di input dell'utente HTML e può essere utilizzato
per il rendering di html personalizzato per i campi del modulo (ad esempio: come una casella di
testo viene renderizzata per l'input del contenuto qui)

attrs sono attributi che verranno copiati così come lo sono per l'html renderizzato per il modulo.

Ad esempio: content.render("name", "Your Name") dà

<input title="Your name" type="text" name="name" value="Your Name" class="form-control" />

Rimozione di un campo modelForm in base alle condizioni di views.py

Se abbiamo un modello come segue,

https://riptutorial.com/it/home 111
from django.db import models
from django.contrib.auth.models import User

class UserModuleProfile(models.Model):
user = models.OneToOneField(User)
expired = models.DateTimeField()
admin = models.BooleanField(default=False)
employee_id = models.CharField(max_length=50)
organisation_name = models.ForeignKey('Organizations', on_delete=models.PROTECT)
country = models.CharField(max_length=100)
position = models.CharField(max_length=100)

def __str__(self):
return self.user

E un modello che utilizza questo modello come segue,

from .models import UserModuleProfile, from django.contrib.auth.models import User


from django import forms

class UserProfileForm(forms.ModelForm):
admin = forms.BooleanField(label="Make this User
Admin",widget=forms.CheckboxInput(),required=False)
employee_id = forms.CharField(label="Employee Id ")
organisation_name = forms.ModelChoiceField(label='Organisation
Name',required=True,queryset=Organizations.objects.all(),empty_label="Select an Organization")
country = forms.CharField(label="Country")
position = forms.CharField(label="Position")

class Meta:
model = UserModuleProfile
fields = ('admin','employee_id','organisation_name','country','position',)

def __init__(self, *args, **kwargs):


admin_check = kwargs.pop('admin_check', False)
super(UserProfileForm, self).__init__(*args, **kwargs)
if not admin_check:
del self.fields['admin']

Si noti che sotto la classe Meta nel modulo ho aggiunto una funzione init che possiamo usare
durante l'inizializzazione del modulo da views.py per eliminare un campo modulo (o alcune altre
azioni). Lo spiegherò più tardi.

Quindi questo modulo può essere utilizzato per scopi di registrazione dell'utente e vogliamo tutti i
campi definiti nella classe Meta del modulo. Ma cosa succede se vogliamo utilizzare lo stesso
modulo quando modifichiamo l'utente, ma quando lo facciamo non vogliamo mostrare il campo
admin del modulo?

Possiamo semplicemente inviare un argomento aggiuntivo quando inizializziamo il modulo in base


ad una logica e cancelliamo il campo admin dal backend.

def edit_profile(request,user_id):
context = RequestContext(request)
user = get_object_or_404(User, id=user_id)
profile = get_object_or_404(UserModuleProfile, user_id=user_id)
admin_check = False

https://riptutorial.com/it/home 112
if request.user.is_superuser:
admin_check = True
# If it's a HTTP POST, we're interested in processing form data.
if request.method == 'POST':
# Attempt to grab information from the raw form information.
profile_form =
UserProfileForm(data=request.POST,instance=profile,admin_check=admin_check)
# If the form is valid...
if profile_form.is_valid():
form_bool = request.POST.get("admin", "xxx")
if form_bool == "xxx":
form_bool_value = False
else:
form_bool_value = True
profile = profile_form.save(commit=False)
profile.user = user
profile.admin = form_bool_value
profile.save()
edited = True
else:
print profile_form.errors

# Not a HTTP POST, so we render our form using ModelForm instance.


# These forms will be blank, ready for user input.
else:
profile_form = UserProfileForm(instance = profile,admin_check=admin_check)

return render_to_response(
'usermodule/edit_user.html',
{'id':user_id, 'profile_form': profile_form, 'edited': edited, 'user':user},
context)

Come puoi vedere ho mostrato qui un semplice esempio di modifica usando il modulo che
abbiamo creato in precedenza. Nota che quando ho inizializzato il modulo ho passato una
variabile admin_check aggiuntiva che contiene True o False .

profile_form = UserProfileForm(instance = profile,admin_check=admin_check)

Ora Se noti il modulo che abbiamo scritto in precedenza puoi vedere che in init proviamo a
catturare il parametro admin_check che passiamo da qui. Se il valore è False, semplicemente
eliminiamo il campo admin dal modulo e lo usiamo. E poiché questo è un modello di modulo, il
campo admin non può essere nullo nel modello, controlliamo semplicemente se il post del modulo
ha il campo admin nel post del modulo, altrimenti lo impostiamo su False nel codice della vista nel
seguente codice della vista.

form_bool = request.POST.get("admin", "xxx")


if form_bool == "xxx":
form_bool_value = False
else:
form_bool_value = True

Upload di file con Django Forms

Prima di tutto dobbiamo aggiungere MEDIA_ROOT e MEDIA_URL al nostro file settings.py

https://riptutorial.com/it/home 113
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

Anche qui lavorerai con ImageField , quindi ricorda di installare in questo caso la libreria Pillow (
pip install pillow ). In caso contrario, si avrà tale errore:

ImportError: No module named PIL

Pillow è un fork di PIL, la Python Imaging Library, che non viene più mantenuta. Il cuscino è
retrocompatibile con PIL.

Django viene fornito con due campi modulo per caricare file sul server, FileField e ImageField , il
seguente è un esempio di utilizzo di questi due campi nel nostro modulo

forms.py:

from django import forms

class UploadDocumentForm(forms.Form):
file = forms.FileField()
image = forms.ImageField()

views.py:

from django.shortcuts import render


from .forms import UploadDocumentForm

def upload_doc(request):
form = UploadDocumentForm()
if request.method == 'POST':
form = UploadDocumentForm(request.POST, request.FILES) # Do not forget to add:
request.FILES
if form.is_valid():
# Do something with our files or simply save them
# if saved, our files would be located in media/ folder under the project's base
folder
form.save()
return render(request, 'upload_doc.html', locals())

upload_doc.html:

<html>
<head>File Uploads</head>
<body>
<form enctype="multipart/form-data" action="" method="post"> <!-- Do not forget to
add: enctype="multipart/form-data" -->
{% csrf_token %}
{{ form }}
<input type="submit" value="Save">
</form>
</body>
</html>

https://riptutorial.com/it/home 114
Convalida dei campi e impegno per modellare (Modifica e-mail utente)

Ci sono già moduli implementati in Django per cambiare la password dell'utente, un esempio è
SetPasswordForm .

Non ci sono, tuttavia, moduli per modificare l'e-mail dell'utente e penso che il seguente esempio
sia importante per capire come utilizzare correttamente un modulo.

L'esempio seguente esegue i seguenti controlli:

• Le e-mail sono infatti cambiate - molto utili se è necessario convalidare l'e-mail o aggiornare
la posta scimpanzè;
• Sia l'e-mail sia l'e-mail di conferma sono le stesse: il modulo ha due campi per l'e-mail,
quindi l'aggiornamento è meno soggetto a errori.

E alla fine, salva la nuova e-mail nell'oggetto utente (aggiorna l'e-mail dell'utente). Si noti che il
metodo __init__() richiede un oggetto utente.

class EmailChangeForm(forms.Form):
"""
A form that lets a user change set their email while checking for a change in the
e-mail.
"""
error_messages = {
'email_mismatch': _("The two email addresses fields didn't match."),
'not_changed': _("The email address is the same as the one already defined."),
}

new_email1 = forms.EmailField(
label=_("New email address"),
widget=forms.EmailInput,
)

new_email2 = forms.EmailField(
label=_("New email address confirmation"),
widget=forms.EmailInput,
)

def __init__(self, user, *args, **kwargs):


self.user = user
super(EmailChangeForm, self).__init__(*args, **kwargs)

def clean_new_email1(self):
old_email = self.user.email
new_email1 = self.cleaned_data.get('new_email1')
if new_email1 and old_email:
if new_email1 == old_email:
raise forms.ValidationError(
self.error_messages['not_changed'],
code='not_changed',
)
return new_email1

def clean_new_email2(self):
new_email1 = self.cleaned_data.get('new_email1')
new_email2 = self.cleaned_data.get('new_email2')

https://riptutorial.com/it/home 115
if new_email1 and new_email2:
if new_email1 != new_email2:
raise forms.ValidationError(
self.error_messages['email_mismatch'],
code='email_mismatch',
)
return new_email2

def save(self, commit=True):


email = self.cleaned_data["new_email1"]
self.user.email = email
if commit:
self.user.save()
return self.user

def email_change(request):
form = EmailChangeForm()
if request.method=='POST':
form = Email_Change_Form(user,request.POST)
if form.is_valid():
if request.user.is_authenticated:
if form.cleaned_data['email1'] == form.cleaned_data['email2']:
user = request.user
u = User.objects.get(username=user)
# get the proper user
u.email = form.cleaned_data['email1']
u.save()
return HttpResponseRedirect("/accounts/profile/")
else:
return render_to_response("email_change.html", {'form':form},
context_instance=RequestContext(request))

Leggi Le forme online: https://riptutorial.com/it/django/topic/1217/le-forme

https://riptutorial.com/it/home 116
Capitolo 30: Meta: linee guida per la
documentazione
Osservazioni
Questa è un'estensione di "Meta: Documentation Guidelines" di Python per Django.

Queste sono solo proposte, non raccomandazioni. Sentiti libero di modificare qualsiasi cosa qui se
non sei d'accordo o hai qualcos'altro da dire.

Examples
Le versioni non supportate non richiedono menzioni speciali

È improbabile che qualcuno usi una versione non supportata di Django, ea proprio rischio. Se mai
qualcuno lo fa, deve preoccuparsi di sapere se esiste una funzionalità nella versione fornita.

Considerando quanto sopra, è inutile menzionare le specificità di una versione non supportata.

1.6

Questo tipo di blocco è inutile perché nessuna persona sana di mente usa Django <1.6.

1.8

Questo tipo di blocco è inutile perché nessuna persona sana di mente usa Django <1,8.

Questo vale anche per gli argomenti. Al momento della stesura di questo esempio, le viste basate
sulla classe 1.3-1.9 versioni supportate sono 1.3-1.9 . Possiamo tranquillamente supporre che
questo sia effettivamente equivalente a All versions . Questo evita anche l'aggiornamento di tutte
le versioni supportate da argomenti ogni volta che viene rilasciata una nuova versione.

Le versioni supportate correnti sono: 1.8 1 1.9 2 1.10 1

1. Correzioni di sicurezza, bug di perdita di dati, bug che si bloccano, bug di funzionalità
importanti nelle funzionalità appena introdotte e regressioni da versioni precedenti di Django.
2. Correzioni di sicurezza e bug di perdita di dati.

Leggi Meta: linee guida per la documentazione online:


https://riptutorial.com/it/django/topic/5243/meta--linee-guida-per-la-documentazione

https://riptutorial.com/it/home 117
Capitolo 31: middleware
introduzione
Middleware in Django è un framework che consente al codice di agganciarsi all'elaborazione di
risposta / richiesta e di modificare l'input o l'output di Django.

Osservazioni
Il middleware deve essere aggiunto all'elenco settings.py MIDDLEWARE_CLASSES prima che venga
incluso nell'esecuzione. L'elenco predefinito che Django fornisce quando si crea un nuovo
progetto è il seguente:

MIDDLEWARE_CLASSES = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

Queste sono tutte funzioni che verranno eseguite in ordine su ogni richiesta (una volta prima che
raggiunga il codice di visualizzazione in views.py e una volta in ordine inverso per la richiamata
process_response , prima della versione 1.10). Fanno una varietà di cose come l'iniezione del token
Cross Site Request Forgery (csrf) .

L'ordine è importante perché se un middleware esegue un reindirizzamento, il middleware


successivo non verrà mai eseguito. O se un middleware si aspetta che il token csrf sia lì, deve
essere eseguito dopo CsrfViewMiddleware .

Examples
Aggiungi dati alle richieste

Django rende davvero facile aggiungere ulteriori dati alle richieste per l'uso all'interno della vista.
Ad esempio, possiamo analizzare il sottodominio sul META della richiesta e collegarlo come una
proprietà separata sulla richiesta utilizzando il middleware.

class SubdomainMiddleware:
def process_request(self, request):
"""
Parse out the subdomain from the request
"""
host = request.META.get('HTTP_HOST', '')
host_s = host.replace('www.', '').split('.')

https://riptutorial.com/it/home 118
request.subdomain = None
if len(host_s) > 2:
request.subdomain = host_s[0]

Se si aggiungono dati con middleware alla richiesta, è possibile accedere a tali dati aggiunti di
recente lungo la linea. Qui utilizzeremo il sottodominio analizzato per determinare qualcosa di
simile a quale organizzazione sta accedendo alla tua applicazione. Questo approccio è utile per le
app distribuite con un'impostazione DNS con sottodomini jolly che puntano tutti a una singola
istanza e la persona che accede all'app desidera che una versione sottoposta a skin sia
dipendente dal punto di accesso.

class OrganizationMiddleware:
def process_request(self, request):
"""
Determine the organization based on the subdomain
"""
try:
request.org = Organization.objects.get(domain=request.subdomain)
except Organization.DoesNotExist:
request.org = None

Ricorda che l'ordine conta quando il middleware dipende l'uno dall'altro. Per le richieste, è
necessario che il middleware dipendente venga inserito dopo la dipendenza.

MIDDLEWARE_CLASSES = [
...
'myapp.middleware.SubdomainMiddleware',
'myapp.middleware.OrganizationMiddleware',
...
]

Middleware da filtrare per indirizzo IP

Primo: la struttura del percorso

Se non ce l'hai, devi creare la cartella middleware all'interno della tua app seguendo la struttura:

yourproject/yourapp/middleware

Il middleware delle cartelle deve essere inserito nella stessa cartella di settings.py, urls, templates
...

Importante: non dimenticare di creare il file init .py vuoto all'interno della cartella
middleware in modo che la tua app riconosca questa cartella

Invece di avere una cartella separata contenente le classi del middleware, è anche possibile
mettere le tue funzioni in un singolo file, yourproject/yourapp/middleware.py .

Secondo: creare il middleware

https://riptutorial.com/it/home 119
Ora dovremmo creare un file per il nostro middleware personalizzato. In questo esempio
supponiamo di volere un middleware che filtra gli utenti in base al loro indirizzo IP, creiamo un file
chiamato filter_ip_middleware.py :

#yourproject/yourapp/middleware/filter_ip_middleware.py
from django.core.exceptions import PermissionDenied

class FilterIPMiddleware(object):
# Check if client IP address is allowed
def process_request(self, request):
allowed_ips = ['192.168.1.1', '123.123.123.123', etc...] # Authorized ip's
ip = request.META.get('REMOTE_ADDR') # Get client IP address
if ip not in allowed_ips:
raise PermissionDenied # If user is not allowed raise Error

# If IP address is allowed we don't do anything


return None

Terzo: aggiungi il middleware nel nostro 'settings.py'

Abbiamo bisogno di cercare il MIDDLEWARE_CLASSES all'interno di settings.py e lì dobbiamo


aggiungere il nostro middleware ( aggiungilo nell'ultima posizione ). Dovrebbe essere come:

MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
# Above are Django standard middlewares

# Now we add here our custom middleware


'yourapp.middleware.filter_ip_middleware.FilterIPMiddleware'
)

Fatto! Ora ogni richiesta da ogni cliente chiamerà il tuo middleware personalizzato ed elaborerà il
tuo codice personalizzato!

Gestione globale delle eccezioni

Supponiamo che tu abbia implementato una logica per rilevare i tentativi di modificare un oggetto
nel database mentre il client che ha presentato le modifiche non ha avuto le ultime modifiche. In
tal caso, si ConfictError(detailed_message) un'eccezione personalizzata
ConfictError(detailed_message) .

Ora si desidera restituire un codice di stato HTTP 409 (Confict) quando si verifica questo errore. In
genere, puoi usarlo come middleware invece di gestirlo in ogni vista che potrebbe sollevare
questa eccezione.

class ConfictErrorHandlingMiddleware:
def process_exception(self, request, exception):
if not isinstance(exception, ConflictError):
return # Propagate other exceptions, we only handle ConflictError

https://riptutorial.com/it/home 120
context = dict(confict_details=str(exception))
return TemplateResponse(request, '409.html', context, status=409)

Comprensione del nuovo stile del middleware Django 1.10

Django 1.10 ha introdotto un nuovo stile middleware in cui process_request e process_response sono
uniti.

In questo nuovo stile, un middleware è un callable che restituisce un altro callable . Bene, in realtà
il primo è una fabbrica di middleware e il secondo è il vero middleware .

La factory middleware prende come argomento singolo il middleware successivo nello stack
middleware o la vista stessa quando viene raggiunto il fondo dello stack.

Il middleware accetta la richiesta come argomento singolo e restituisce sempre un HttpResponse .

Il miglior esempio per illustrare come funziona il middleware di nuovo stile è probabilmente quello
di mostrare come creare un middleware compatibile con le versioni precedenti:

class MyMiddleware:

def __init__(self, next_layer=None):


"""We allow next_layer to be None because old-style middlewares
won't accept any argument.
"""
self.get_response = next_layer

def process_request(self, request):


"""Let's handle old-style request processing here, as usual."""
# Do something with request
# Probably return None
# Or return an HttpResponse in some cases

def process_response(self, request, response):


"""Let's handle old-style response processing here, as usual."""
# Do something with response, possibly using request.
return response

def __call__(self, request):


"""Handle new-style middleware here."""
response = self.process_request(request)
if response is None:
# If process_request returned None, we must call the next middleware or
# the view. Note that here, we are sure that self.get_response is not
# None because this method is executed only in new-style middlewares.
response = self.get_response(request)
response = self.process_response(request, response)
return response

Leggi middleware online: https://riptutorial.com/it/django/topic/1721/middleware

https://riptutorial.com/it/home 121
Capitolo 32: migrazioni
Parametri

comando di django-admin Dettagli

makemigrations <my_app> Genera migrazioni per my_app

makemigrations Genera migrazioni per tutte le app

makemigrations --merge Risolvi i conflitti di migrazione per tutte le app

makemigrations --merge <my_app> Risolvi i conflitti di migrazione per my_app

makemigrations --name <migration_name> Genera una migrazione per my_app con il nome
<my_app> migration_name

Applica le migrazioni in sospeso di my_app al


migrate <my_app>
database

migrate Applica tutte le migrazioni in sospeso al database

migrate <my_app> <migration_name> Applica o disattiva fino a migration_name

migrate <my_app> zero Annulla l'applicazione di tutte le migrazioni in


my_app

sqlmigrate <my_app> <migration_name> Stampa l'SQL per la migrazione denominata

showmigrations Mostra tutte le migrazioni per tutte le app

showmigrations <my_app> Mostra tutte le migrazioni in my_app

Examples
Lavorare con le migrazioni

Django usa le migrazioni per propagare le modifiche apportate ai tuoi modelli al tuo database. Il
più delle volte django può generarli per te.

Per creare una migrazione, esegui:

$ django-admin makemigrations <app_name>

Questo creerà un file di migrazione nel sottomodulo di migration di app_name . La prima migrazione
sarà denominata 0001_initial.py , l'altra inizierà con 0002_ , quindi 0003 , ...

https://riptutorial.com/it/home 122
Se ometti <app_name> questo creerà le migrazioni per tutti i tuoi INSTALLED_APPS .

Per propagare le migrazioni al tuo database, esegui:

$ django-admin migrate <app_name>

Per mostrare tutte le tue migrazioni, esegui:

$ django-admin showmigrations app_name


app_name
[X] 0001_initial
[X] 0002_auto_20160115_1027
[X] 0003_somemodel
[ ] 0004_auto_20160323_1826

• [X] significa che la migrazione è stata propagata al tuo database


• [ ] significa che la migrazione non è stata propagata al tuo database. Usa la django-admin
migrate di django-admin migrate per propagarlo

Chiama anche ripristinare le migrazioni, questo può essere fatto passando il nome della migrate
command . Dato l'elenco di migrazioni di cui sopra (mostrato da django-admin showmigrations ):

$ django-admin migrate app_name 0002 # Roll back to migration 0002


$ django-admin showmigrations app_name
app_name
[X] 0001_initial
[X] 0002_auto_20160115_1027
[ ] 0003_somemodel
[ ] 0004_auto_20160323_1826

Migrazioni manuali

A volte, le migrazioni generate da Django non sono sufficienti. Ciò è particolarmente vero quando
si desidera effettuare migrazioni di dati .

Ad esempio, disponiamo di tale modello:

class Article(models.Model):
title = models.CharField(max_length=70)

Questo modello ha già dati esistenti e ora vuoi aggiungere uno SlugField :

class Article(models.Model):
title = models.CharField(max_length=70)
slug = models.SlugField(max_length=70)

Hai creato le migrazioni per aggiungere il campo, ma ora ti piacerebbe impostare lo slug per tutti
gli articoli esistenti, in base al loro title .

Certo, potresti semplicemente fare qualcosa del genere nel terminale:

https://riptutorial.com/it/home 123
$ django-admin shell
>>> from my_app.models import Article
>>> from django.utils.text import slugify
>>> for article in Article.objects.all():
... article.slug = slugify(article.title)
... article.save()
...
>>>

Ma dovrai farlo in tutti i tuoi ambienti (ad esempio il tuo desktop dell'ufficio, il tuo laptop, ...), tutti i
tuoi colleghi dovranno farlo anche tu, e dovrai pensarci su come mettere in scena e quando spingi
vivere.

Per farlo una volta per tutte, lo faremo in una migrazione. Per prima cosa crea una migrazione
vuota:

$ django-admin makemigrations --empty app_name

Questo creerà un file di migrazione vuoto. Aprilo, contiene uno scheletro di base. Supponiamo che
la tua precedente migrazione sia stata denominata 0023_article_slug e che questa sia denominata
0024_auto_20160719_1734 . Ecco cosa scriveremo nel nostro file di migrazione:

# -*- coding: utf-8 -*-


# Generated by Django 1.9.7 on 2016-07-19 15:34
from __future__ import unicode_literals

from django.db import migrations


from django.utils.text import slugify

def gen_slug(apps, schema_editor):


# We can't import the Article model directly as it may be a newer
# version than this migration expects. We use the historical version.
Article = apps.get_model('app_name', 'Article')
for row in Article.objects.all():
row.slug = slugify(row.name)
row.save()

class Migration(migrations.Migration):

dependencies = [
('hosting', '0023_article_slug'),
]

operations = [
migrations.RunPython(gen_slug, reverse_code=migrations.RunPython.noop),
# We set `reverse_code` to `noop` because we cannot revert the migration
# to get it back in the previous state.
# If `reverse_code` is not given, the migration will not be reversible,
# which is not the behaviour we expect here.
]

Migrazioni false

https://riptutorial.com/it/home 124
Quando viene eseguita una migrazione, Django memorizza il nome della migrazione in una tabella
django_migrations.

Crea e simula le migrazioni iniziali per lo schema esistente

Se la tua app ha già modelli e tabelle di database e non ha migrazioni. Per prima cosa crea le
migrazioni iniziali per la tua app.

python manage.py makemigrations your_app_label

Ora false migrazioni iniziali come applicate

python manage.py migrate --fake-initial

Fake tutte le migrazioni in tutte le app

python manage.py migrate --fake

Migrazioni di app singole false

python manage.py migrate --fake core

File di migrazione singola falso

python manage.py migrate myapp migration_name

Nomi personalizzati per i file di migrazione

Utilizzare l' makemigrations --name <your_migration_name> per consentire la denominazione delle


migrazioni (s) anziché utilizzare un nome generato.

python manage.py makemigrations --name <your_migration_name> <app_name>

Risolvere i conflitti di migrazione

introduzione
A volte le migrazioni entrano in conflitto, con il risultato di rendere la migrazione non riuscita.
Questo può accadere in un sacco di scenerio, tuttavia può verificarsi regolarmente durante lo
sviluppo di un'app con un team.

I conflitti di migrazione comuni si verificano durante l'utilizzo del controllo del codice sorgente,
soprattutto quando viene utilizzato il metodo funzione-per-ramo. Per questo scenario useremo un
modello chiamato Reporter con gli attributi name e address .

Due sviluppatori a questo punto svilupperanno una funzionalità, quindi entrambi avranno questa

https://riptutorial.com/it/home 125
copia iniziale del modello Reporter . Lo sviluppatore A aggiunge age che risulta nel file
0002_reporter_age.py . Lo sviluppatore B aggiunge un campo bank_account che viene
0002_reporter_bank_account in 0002_reporter_bank_account . Una volta che questi sviluppatori
uniscono il loro codice e tentano di migrare le migrazioni, si è verificato un conflitto di migrazione.

Questo conflitto si verifica perché queste migrazioni modificano entrambi lo stesso modello,
Reporter . Inoltre, i nuovi file iniziano entrambi con 0002.

Unione di migrazioni
Ci sono diversi modi per farlo. Quanto segue è nell'ordine consigliato:

1. La soluzione più semplice è eseguire il comando makemigrations con un flag --merge.

python manage.py makemigrations --merge <my_app>

Questo creerà una nuova migrazione per risolvere il conflitto precedente.

2. Quando questo file extra non è benvenuto nell'ambiente di sviluppo per motivi personali,
un'opzione è quella di eliminare le migrazioni in conflitto. Quindi, è possibile eseguire una
nuova migrazione utilizzando il normale comando makemigrations . Quando vengono scritte le
migrazioni personalizzate, ad esempio migrations.RunPython , è necessario tenere conto
dell'utilizzo di questo metodo.

Cambia un CharField in un ForeignKey

Prima di tutto, supponiamo che questo sia il tuo modello iniziale, all'interno di un'applicazione
chiamata discography :

from django.db import models

class Album(models.Model):
name = models.CharField(max_length=255)
artist = models.CharField(max_length=255)

Ora, ti rendi conto che vuoi usare una ForeignKey per l'artista. Questo è un processo un po
'complesso, che deve essere fatto in diversi passaggi.

Passaggio 1, aggiungere un nuovo campo per ForeignKey, assicurandosi di contrassegnarlo


come null (si noti che ora è incluso anche il modello a cui stiamo collegando):

from django.db import models

class Album(models.Model):
name = models.CharField(max_length=255)
artist = models.CharField(max_length=255)
artist_link = models.ForeignKey('Artist', null=True)

class Artist(models.Model):
name = models.CharField(max_length=255)

https://riptutorial.com/it/home 126
... e creare una migrazione per questo cambiamento.

./manage.py makemigrations discography

Passaggio 2, compilare il nuovo campo. Per fare ciò, devi creare una migrazione vuota.

./manage.py makemigrations --empty --name transfer_artists discography

Una volta che hai questa migrazione vuota, vuoi aggiungere una singola operazione RunPython ad
essa per collegare i tuoi record. In questo caso, potrebbe assomigliare a questo:

def link_artists(apps, schema_editor):


Album = apps.get_model('discography', 'Album')
Artist = apps.get_model('discography', 'Artist')
for album in Album.objects.all():
artist, created = Artist.objects.get_or_create(name=album.artist)
album.artist_link = artist
album.save()

Ora che i tuoi dati vengono trasferiti nel nuovo campo, potresti effettivamente essere fatto e
lasciare tutto come è, usando il nuovo campo artist_link per tutto. Oppure, se vuoi fare un po 'di
pulizia, vuoi creare altre due migrazioni.

Per la tua prima migrazione, vorrai cancellare il tuo campo originale, artist . Per la tua seconda
migrazione, rinomina il nuovo campo artist_link con l' artist .

Questo viene fatto in più passaggi per garantire che Django riconosca le operazioni correttamente.

Leggi migrazioni online: https://riptutorial.com/it/django/topic/1200/migrazioni

https://riptutorial.com/it/home 127
Capitolo 33: Modelli
introduzione
Nel caso base, un modello è una classe Python che esegue il mapping su una singola tabella di
database. Gli attributi della mappa della classe alle colonne nella tabella e un'istanza della classe
rappresentano una riga nella tabella del database. I modelli ereditano da django.db.models.Model
che fornisce una ricca API per aggiungere e filtrare i risultati dal database.

Crea il tuo primo modello

Examples
Creare il tuo primo modello

I modelli sono in genere definiti nel file models.py nella sottodirectory dell'applicazione. La classe
Model del modulo django.db.models è una buona classe iniziale per estendere i tuoi modelli. Per
esempio:

from django.db import models

class Book(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey('Author', on_delete=models.CASCADE,
related_name='authored_books')
publish_date = models.DateField(null=True, blank=True)

def __str__(self): # __unicode__ in python 2.*


return self.title

Ogni attributo in un modello rappresenta una colonna nel database.

• è un testo con una lunghezza massima di 100 caratteri


title
• author è un ForeignKey che rappresenta una relazione con un altro modello / tabella, in
questo caso Author (usato solo per scopi di esempio). on_delete dice al database cosa fare
con l'oggetto se l'oggetto correlato (un Author ) viene cancellato. (Va notato che dal momento
che django 1.9 on_delete può essere utilizzato come secondo argomento posizionale, in
django 2 è un argomento obbligatorio ed è consigliabile trattarlo come tale
immediatamente. Nelle versioni precedenti verrà on_delete come predefinito su CASCADE .)
• publish_date memorizza una data. Sia null che blank sono impostati su True per indicare che
non si tratta di un campo obbligatorio (ovvero è possibile aggiungerlo in un secondo
momento o lasciarlo vuoto).

Insieme agli attributi definiamo un metodo __str__ questo restituisce il titolo del libro che verrà
usato come rappresentazione di string dove necessario, piuttosto che come predefinito.

Applicazione delle modifiche al database (Migrazioni)

https://riptutorial.com/it/home 128
Dopo aver creato un nuovo modello o modificato i modelli esistenti, sarà necessario generare
migrazioni per le modifiche e quindi applicare le migrazioni al database specificato. Questo può
essere fatto usando il sistema di migrazione integrato di Django. Utilizzo dell'utilità manage.py nella
directory root del progetto:

python manage.py makemigrations <appname>

Il comando precedente creerà gli script di migrazione necessari nella sottodirectory delle
migrations dell'applicazione. Se si omette il parametro <appname> , verranno elaborate tutte le
applicazioni definite nell'argomento INSTALLED_APPS di settings.py . Se lo ritieni necessario, puoi
modificare le migrazioni.

È possibile controllare quali migrazioni sono richieste senza effettivamente creare la migrazione
utilizzare l'opzione --dry-run, ad esempio:

python manage.py makemigrations --dry-run

Per applicare le migrazioni:

python manage.py migrate <appname>

Il comando precedente eseguirà gli script di migrazione generati nel primo passaggio e aggiornerà
fisicamente il database.

Se il modello del database esistente viene modificato, è necessario il seguente comando per
apportare le modifiche necessarie.

python manage.py migrate --run-syncdb

Django creerà la tabella con il nome <appname>_<classname> per impostazione predefinita. A volte
non vuoi usarlo. Se vuoi cambiare il nome predefinito, puoi annunciare il nome della tabella
impostando db_table nella classe Meta :

from django.db import models

class YourModel(models.Model):
parms = models.CharField()
class Meta:
db_table = "custom_table_name"

Se vuoi vedere quale codice SQL verrà eseguito da una certa migrazione, esegui questo
comando:

python manage.py sqlmigrate <app_label> <migration_number>

Django> 1.10
La nuova opzione makemigrations --check rende il comando di uscita con uno stato diverso da zero
quando vengono rilevate modifiche del modello senza migrazioni.

https://riptutorial.com/it/home 129
Vedi Migrazioni per maggiori dettagli sulle migrazioni.

Creare un modello con relazioni

Relazione molti-a-uno

from django.db import models

class Author(models.Model):
name = models.CharField(max_length=50)

#Book has a foreignkey (many to one) relationship with author


class Book(models.Model):
author = models.ForeignKey(Author, on_delete=models.CASCADE)
publish_date = models.DateField()

Opzione più generica. Può essere utilizzato ovunque tu voglia rappresentare una relazione

Relazione molti-a-molti

class Topping(models.Model):
name = models.CharField(max_length=50)

# One pizza can have many toppings and same topping can be on many pizzas
class Pizza(models.Model):
name = models.CharField(max_length=50)
toppings = models.ManyToManyField(Topping)

Internamente questo è rappresentato tramite un'altra tabella. E ManyToManyField dovrebbe essere


messo su modelli che saranno modificati su un modulo. Ad esempio: l' Appointment avrà un
ManyToManyField chiamato Customer , Pizza ha Toppings e così via.

Relazione molti-a-molti utilizzando le classi Through

class Service(models.Model):
name = models.CharField(max_length=35)

class Client(models.Model):
name = models.CharField(max_length=35)
age = models.IntegerField()
services = models.ManyToManyField(Service, through='Subscription')

class Subscription(models.Model):
client = models.ForeignKey(Client)
service = models.ForeignKey(Service)
subscription_type = models.CharField(max_length=1, choices=SUBSCRIPTION_TYPES)
created_at = models.DateTimeField(default=timezone.now)

In questo modo, possiamo effettivamente mantenere più metadati su una relazione tra due entità.
Come si può vedere, un cliente può essere abbonato a diversi servizi tramite diversi tipi di
abbonamento. L'unica differenza in questo caso è che per aggiungere nuove istanze alla relazione
M2M, non è possibile utilizzare il metodo di scelta rapida pizza.toppings.add(topping) , invece,
dovrebbe essere creato un nuovo oggetto della classe through ,
Subscription.objects.create(client=client, service=service, subscription_type='p')

https://riptutorial.com/it/home 130
In altre lingue, le through tables sono anche note come JoinColumn , Intersection table
o mapping table

Relazione uno-a-uno

class Employee(models.Model):
name = models.CharField(max_length=50)
age = models.IntegerField()
spouse = models.OneToOneField(Spouse)

class Spouse(models.Model):
name = models.CharField(max_length=50)

Usa questi campi quando avrai sempre una relazione di composizione tra i due modelli.

Query di base su Django DB

Django ORM è un'astrazione potente che ti consente di archiviare e recuperare dati dal database
senza dover scrivere query SQL.

Assumiamo i seguenti modelli:

class Author(models.Model):
name = models.CharField(max_length=50)

class Book(models.Model):
name = models.CharField(max_length=50)
author = models.ForeignKey(Author)

Supponendo che tu abbia aggiunto il codice sopra a un'applicazione django ed esegui il comando
migrate (in modo che il tuo database sia creato). Inizia la shell di Django di

python manage.py shell

Questo avvia la shell python standard ma con importate librerie Django rilevanti, in modo che tu
possa concentrarti direttamente sulle parti importanti.

Inizia importando i modelli che abbiamo appena definito (presumo che ciò avvenga in un file
models.py )

from .models import Book, Author

Esegui la tua prima query di selezione:

>>> Author.objects.all()
[]
>>> Book.objects.all()
[]

Consente di creare un autore e un oggetto libro:

https://riptutorial.com/it/home 131
>>> hawking = Author(name="Stephen hawking")
>>> hawking.save()
>>> history_of_time = Book(name="history of time", author=hawking)
>>> history_of_time.save()

oppure utilizzare la funzione crea per creare oggetti modello e salvare in un codice di linea

>>> wings_of_fire = Book.objects.create(name="Wings of Fire", author="APJ Abdul Kalam")

Ora consente di eseguire la query

>>> Book.objects.all()
[<Book: Book object>]
>>> book = Book.objects.first() #getting the first book object
>>> book.name
u'history of time'

Aggiungiamo una clausola where alla nostra query select

>>> Book.objects.filter(name='nothing')
[]
>>> Author.objects.filter(name__startswith='Ste')
[<Author: Author object>]

Per ottenere i dettagli sull'autore di un determinato libro

>>> book = Book.objects.first() #getting the first book object


>>> book.author.name # lookup on related model
u'Stephen hawking'

Per ottenere tutti i libri pubblicati da Stephen Hawking (libro Lookup dal suo autore)

>>> hawking.book_set.all()
[<Book: Book object>]

_setè la notazione usata per "Reverse lookups" cioè, mentre il campo di ricerca è sul modello
Book, possiamo usare book_set su un oggetto autore per ottenere tutti i suoi libri.

Un tavolo non gestito di base.

Ad un certo punto del tuo utilizzo di Django, potresti trovarti a voler interagire con le tabelle che
sono già state create o con le viste del database. In questi casi, non vorrai che Django gestisca le
tabelle attraverso le sue migrazioni. Per impostare questo, è necessario aggiungere solo una
variabile alla classe Meta del modello: managed = False .

Ecco un esempio di come è possibile creare un modello non gestito per interagire con una vista
del database:

class Dummy(models.Model):
something = models.IntegerField()

https://riptutorial.com/it/home 132
class Meta:
managed = False

Questo può essere associato a una vista definita in SQL come segue.

CREATE VIEW myapp_dummy AS


SELECT id, something FROM complicated_table
WHERE some_complicated_condition = True

Una volta creato questo modello, puoi utilizzarlo come faresti con qualsiasi altro modello:

>>> Dummy.objects.all()
[<Dummy: Dummy object>, <Dummy: Dummy object>, <Dummy: Dummy object>]
>>> Dummy.objects.filter(something=42)
[<Dummy: Dummy object>]

Modelli avanzati

Un modello può fornire molte più informazioni rispetto ai soli dati su un oggetto. Vediamo un
esempio e scomporlo in ciò che è utile per:

from django.db import models


from django.urls import reverse
from django.utils.encoding import python_2_unicode_compatible

@python_2_unicode_compatible
class Book(models.Model):
slug = models.SlugField()
title = models.CharField(max_length=128)
publish_date = models.DateField()

def get_absolute_url(self):
return reverse('library:book', kwargs={'pk':self.pk})

def __str__(self):
return self.title

class Meta:
ordering = ['publish_date', 'title']

Chiave primaria automatica


Potresti notare l'uso di self.pk nel metodo get_absolute_url . Il campo pk è un alias della chiave
primaria di un modello. Inoltre, Django aggiungerà automaticamente una chiave primaria se
manca. Questa è una cosa in meno di cui preoccuparsi e ti consente di impostare la chiave
esterna per qualsiasi modello e ottenerli facilmente.

URL assoluto
La prima funzione definita è get_absolute_url . In questo modo, se si dispone di un libro, è

https://riptutorial.com/it/home 133
possibile ottenere un collegamento ad esso senza manipolare il tag url, risolvere, attributo e simili.
Chiama semplicemente book.get_absolute_url e ottieni il link giusto. Come bonus, il tuo oggetto
nell'amministratore di django otterrà un pulsante "Visualizza sul sito".

Rappresentazione delle stringhe


Avere un metodo __str__ consente di utilizzare l'oggetto quando è necessario visualizzarlo. Ad
esempio, con il metodo precedente, aggiungere un link al libro in un modello è semplice come <a
href="{{ book.get_absolute_url }}">{{ book }}</a> . Dritto al punto. Questo metodo controlla anche
ciò che viene visualizzato nel menu a discesa dell'amministratore, ad esempio per la chiave
esterna.

Il decoratore di classi ti consente di definire il metodo una volta sia per __str__ che __unicode__ su
python 2 senza causare alcun problema su python 3. Se ti aspetti che la tua app funzioni su
entrambe le versioni, questa è la strada da percorrere.

Campo di lumaca
Il campo slug è simile a un campo char ma accetta meno simboli. Per impostazione predefinita,
solo lettere, numeri, caratteri di sottolineatura o trattini. È utile se vuoi identificare un oggetto
usando una bella rappresentazione, ad esempio nell'URL.

La classe Meta
La classe Meta ci consente di definire molte più informazioni sull'intera collezione di oggetti. Qui è
impostato solo l'ordine predefinito. Ad esempio, è utile con l'oggetto ListView. Prende una lista
ideale di campo da usare per l'ordinamento. Qui, il libro verrà ordinato prima per data di
pubblicazione e poi per titolo se la data è la stessa.

Gli altri attributi di frequenza sono verbose_name e verbose_name_plural . Di default, sono generati dal
nome del modello e dovrebbero andare bene. Ma la forma plurale è ingenua, semplicemente
aggiungendo un 's' al singolare, quindi potresti volerlo impostare in modo esplicito in alcuni casi.

Valori calcolati

Una volta che un oggetto modello è stato recuperato, diventa un'istanza pienamente realizzata
della classe. Di conseguenza, è possibile accedere a qualsiasi metodo aggiuntivo nei moduli e nei
serializzatori (come Django Rest Framework).

L'utilizzo delle proprietà python è un modo elegante per rappresentare valori aggiuntivi che non
sono memorizzati nel database a causa di circostanze variabili.

def expire():
return timezone.now() + timezone.timedelta(days=7)

class Coupon(models.Model):
expiration_date = models.DateField(default=expire)

https://riptutorial.com/it/home 134
@property
def is_expired(self):
return timezone.now() > self.expiration_date

Mentre nella maggior parte dei casi è possibile integrare dati con annotazioni sui propri querysets,
i valori calcolati come proprietà del modello sono ideali per i calcoli che non possono essere
valutati semplicemente nell'ambito di una query.

Inoltre, le proprietà, dal momento che sono dichiarate sulla classe python e non come parte dello
schema, non sono disponibili per l'esecuzione di query.

Aggiunta di una rappresentazione di stringa di un modello

Per creare una presentazione leggibile dall'uomo di un oggetto modello è necessario


implementare il metodo Model.__str__() (o Model.__unicode__() su python2). Questo metodo verrà
chiamato ogni volta che si chiama str() su un'istanza del modello (incluso, ad esempio, quando il
modello viene utilizzato in un modello). Ecco un esempio:

1. Crea un modello di libro.

# your_app/models.py

from django.db import models

class Book(models.Model):
name = models.CharField(max_length=50)
author = models.CharField(max_length=50)

2. Crea un'istanza del modello e salvala nel database:

>>> himu_book = Book(name='Himu Mama', author='Humayun Ahmed')


>>> himu_book.save()

3. Esegui print() sull'istanza:

>>> print(himu_book)
<Book: Book object>

<Book: Book object> , l'output predefinito, non ci è di aiuto. Per risolvere questo problema,
aggiungiamo un metodo __str__ .

from django.utils.encoding import python_2_unicode_compatible

@python_2_unicode_compatible
class Book(models.Model):
name = models.CharField(max_length=50)
author = models.CharField(max_length=50)

def __str__(self):
return '{} by {}'.format(self.name, self.author)

https://riptutorial.com/it/home 135
Nota che il decoratore python_2_unicode_compatible è necessario solo se vuoi che il tuo codice sia
compatibile con python 2. Questo decoratore copia il metodo __str__ per creare un metodo
__unicode__ . django.utils.encoding da django.utils.encoding .

Ora se chiamiamo nuovamente la funzione di stampa l'istanza del libro:

>>> print(himu_book)
Himu Mama by Humayun Ahmed

Molto meglio!

La rappresentazione della stringa viene anche utilizzata quando il modello viene utilizzato in un
campo ModelForm per i campi ForeignKeyField e ManyToManyField .

Model mixins

Negli stessi casi, diversi modelli potrebbero avere gli stessi campi e le stesse procedure nel ciclo
di vita del prodotto. Per gestire queste somiglianze senza avere l'ereditarietà di ripetizione del
codice potrebbe essere utilizzato. Invece di ereditare un'intera classe, il modello di progettazione
mixin ci consente di ereditare ( o alcuni include include ) alcuni metodi e attributi. Vediamo un
esempio:

class PostableMixin(models.Model):
class Meta:
abstract=True

sender_name = models.CharField(max_length=128)
sender_address = models.CharField(max_length=255)
receiver_name = models.CharField(max_length=128)
receiver_address = models.CharField(max_length=255)
post_datetime = models.DateTimeField(auto_now_add=True)
delivery_datetime = models.DateTimeField(null=True)
notes = models.TextField(max_length=500)

class Envelope(PostableMixin):
ENVELOPE_COMMERCIAL = 1
ENVELOPE_BOOKLET = 2
ENVELOPE_CATALOG = 3

ENVELOPE_TYPES = (
(ENVELOPE_COMMERCIAL, 'Commercial'),
(ENVELOPE_BOOKLET, 'Booklet'),
(ENVELOPE_CATALOG, 'Catalog'),
)

envelope_type = models.PositiveSmallIntegerField(choices=ENVELOPE_TYPES)

class Package(PostableMixin):
weight = models.DecimalField(max_digits=6, decimal_places=2)
width = models.DecimalField(max_digits=5, decimal_places=2)
height = models.DecimalField(max_digits=5, decimal_places=2)
depth = models.DecimalField(max_digits=5, decimal_places=2)

Per trasformare un modello in una classe astratta, dovrai menzionare abstract=True nella sua

https://riptutorial.com/it/home 136
classe Meta interna. Django non crea tabelle per i modelli astratti nel database. Tuttavia, per i
modelli Envelope e Package , le tabelle corrispondenti verranno create nel database.

Inoltre i campi alcuni metodi modello saranno necessari in più di un modello. Quindi questi metodi
potrebbero essere aggiunti ai mixin per prevenire la ripetizione del codice. Ad esempio, se
creiamo un metodo per impostare la data di consegna su PostableMixin , sarà accessibile da
entrambi i suoi figli:

class PostableMixin(models.Model):
class Meta:
abstract=True

...
...

def set_delivery_datetime(self, dt=None):


if dt is None:
from django.utils.timezone import now
dt = now()

self.delivery_datetime = dt
self.save()

Questo metodo potrebbe essere usato come segue sui bambini:

>> envelope = Envelope.objects.get(pk=1)


>> envelope.set_delivery_datetime()

>> pack = Package.objects.get(pk=1)


>> pack.set_delivery_datetime()

Chiave primaria UUID

Un modello per impostazione predefinita utilizza una chiave primaria con incremento automatico
(numero intero). Questo ti darà una sequenza di chiavi 1, 2, 3.

Diversi tipi di chiavi primarie possono essere impostati su un modello con piccole modifiche al
modello.

Un UUID è un identificatore univoco universale, si tratta di un identificatore casuale a 32 caratteri


che può essere utilizzato come ID. Questa è una buona opzione da utilizzare quando non si
desidera che ID sequenziali siano assegnati ai record nel proprio database. Se usato su
PostgreSQL, questo memorizza in un tipo di dati uuid, altrimenti in un char (32).

import uuid
from django.db import models

class ModelUsingUUID(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

La chiave generata sarà nel formato 7778c552-73fc-4bc4-8bf9-5a2f6f7b7f47

https://riptutorial.com/it/home 137
Eredità

L'ereditarietà tra i modelli può essere effettuata in due modi:

• una classe astratta comune (vedi l'esempio "Model mixins")


• un modello comune con più tabelle

L'ereditarietà di più tabelle creerà una tabella per i campi comuni e uno per esempio di modello
figlio:

from django.db import models

class Place(models.Model):
name = models.CharField(max_length=50)
address = models.CharField(max_length=80)

class Restaurant(Place):
serves_hot_dogs = models.BooleanField(default=False)
serves_pizza = models.BooleanField(default=False)

creerà 2 tabelle, una per il Place e una per il Restaurant con un campo OneToOne nascosto da Place
per i campi comuni.

si noti che questo richiederà una query aggiuntiva alle tabelle dei luoghi ogni volta che si recupera
un oggetto ristorante.

Leggi Modelli online: https://riptutorial.com/it/django/topic/888/modelli

https://riptutorial.com/it/home 138
Capitolo 34: Processori di contesto
Osservazioni
Utilizza processori di contesto per aggiungere variabili accessibili ovunque nei tuoi modelli.

Specificare una funzione, o funzioni che restituiscono le dict delle variabili desiderate, quindi
aggiungere tali funzioni a TEMPLATE_CONTEXT_PROCESSORS .

Examples
Utilizzare un processore di contesto per accedere alle impostazioni.DEBUG
nei modelli

in myapp/context_processors.py :

from django.conf import settings

def debug(request):
return {'DEBUG': settings.DEBUG}

in settings.py :

TEMPLATES = [
{
...
'OPTIONS': {
'context_processors': [
...
'myapp.context_processors.debug',
],
},
},
]

oppure, per le versioni <1.9:

TEMPLATE_CONTEXT_PROCESSORS = (
...
'myapp.context_processors.debug',
)

Quindi nei miei modelli, semplicemente:

{% if DEBUG %} .header { background:#f00; } {% endif %}


{{ DEBUG }}

Utilizzo di un processore di contesto per accedere alle voci del blog più

https://riptutorial.com/it/home 139
recenti in tutti i modelli

Supponendo che tu abbia un modello definito Post definito nel tuo file models.py che contiene post
di blog e che abbia un campo date_published .

Passaggio 1: scrivere il processore di contesto

Crea (o aggiungi a) un file nella tua directory app denominata context_processors.py :

from myapp.models import Post

def recent_blog_posts(request):
return {'recent_posts':Post.objects.order_by('-date_published')[0:3],} # Can change
numbers for more/fewer posts

Passaggio 2: aggiungere il processore di contesto al file delle impostazioni

Assicurati di aggiungere il nuovo processore di contesto al file settings.py nella variabile TEMPLATES
:

TEMPLATES = [
{
...
'OPTIONS': {
'context_processors': [
...
'myapp.context_processors.recent_blog_posts',
],
},
},
]

(Nelle versioni di Django precedenti alla 1.9, questo era impostato direttamente in settings.py
usando una variabile TEMPLATE_CONTEXT_PROCESSORS .)

Passaggio 3: utilizzare il processore di contesto nei modelli

Non è più necessario passare più recenti post di blog attraverso le singole visualizzazioni! Basta
usare recent_blog_posts in qualsiasi modello.

Ad esempio, in home.html puoi creare una barra laterale con link a post recenti:

<div class="blog_post_sidebar">
{% for post in recent_blog_posts %}
<div class="post">
<a href="{{post.get_absolute_url}}">{{post.title}}</a>
</div>
{% endfor %}
</div>

https://riptutorial.com/it/home 140
Oppure in blog.html potresti creare una visualizzazione più dettagliata di ogni post:

<div class="content">
{% for post in recent_blog_posts %}
<div class="post_detail">
<h2>{{post.title}}</h2>
<p>Published on {{post.date_published}}</p>
<p class="author">Written by: {{post.author}}</p>
<p><a href="{{post.get_absolute_url}}">Permalink</a></p>
<p class="post_body">{{post.body}}</p>
</div>
{% endfor %}
</div>

Estendere i tuoi modelli

Processore di contesto per determinare il modello in base all'appartenenza al gruppo (oa qualsiasi
query / logica). Ciò consente ai nostri utenti pubblici / regolari di ottenere un modello e il nostro
gruppo speciale per ottenerne uno diverso.

frontend / context_processors.py

def template_selection(request):
site_template = 'template_public.html'
if request.user.is_authenticated():
if request.user.groups.filter(name="some_group_name").exists():
site_template = 'template_new.html'

return {
'site_template': site_template,
}

Aggiungi il processore di contesto alle tue impostazioni.

Nei modelli, utilizzare la variabile definita nel processore di contesto.

{% extends site_template %}

Leggi Processori di contesto online: https://riptutorial.com/it/django/topic/491/processori-di-


contesto

https://riptutorial.com/it/home 141
Capitolo 35: RangeFields: un gruppo di
campi specifici di PostgreSQL
Sintassi
• dall'importazione django.contrib.postgres.fields * RangeField
• IntegerRangeField (** opzioni)
• BigIntegerRangeField (** opzioni)
• FloatRangeField (** opzioni)
• DateTimeRangeField (** opzioni)
• DateRangeField (** opzioni)

Examples
Compresi i campi dell'intervallo numerico nel modello

Ci sono tre tipi di RangeField numerici in Python. IntegerField , BigIntegerField e FloatField .


psycopg2 in psycopg2 NumericRange s, ma accettano input come tuple Python native. Il limite
inferiore è incluso e il limite superiore è escluso.

class Book(models.Model):
name = CharField(max_length=200)
ratings_range = IntegerRange()

Impostazione per RangeField

1. aggiungi 'django.contrib.postgres' ai tuoi INSTALLED_APPS


2. installa psycopg2

Creazione di modelli con campi intervallo numerico

È più semplice e più semplice inserire valori come una tupla Python invece di un NumericRange .

Book.objects.create(name='Pro Git', ratings_range=(5, 5))

Metodo alternativo con NumericRange :

Book.objects.create(name='Pro Git', ratings_range=NumericRange(5, 5))

L'utilizzo contiene

Questa query seleziona tutti i libri con una valutazione inferiore a tre.

https://riptutorial.com/it/home 142
bad_books = Books.objects.filter(ratings_range__contains=(1, 3))

Utilizzando contenuto_by

Questa query ottiene tutti i libri con valutazioni superiori o uguali a zero e inferiori a sei.

all_books = Book.objects.filter(ratings_range_contained_by=(0, 6))

Usando la sovrapposizione

Questa query ottiene tutti gli appuntamenti sovrapposti da sei a dieci.

Appointment.objects.filter(time_span__overlap=(6, 10))

Usando Nessuna per indicare nessun limite superiore

Questa query seleziona tutti i libri con una valutazione superiore o uguale a quattro.

maybe_good_books = Books.objects.filter(ratings_range__contains=(4, None))

Varia le operazioni

from datetime import timedelta

from django.utils import timezone


from psycopg2.extras import DateTimeTZRange

# To create a "period" object we will use psycopg2's DateTimeTZRange


# which takes the two datetime bounds as arguments
period_start = timezone.now()
period_end = period_start + timedelta(days=1, hours=3)
period = DateTimeTZRange(start, end)

# Say Event.timeslot is a DateTimeRangeField

# Events which cover at least the whole selected period,


Event.objects.filter(timeslot__contains=period)

# Events which start and end within selected period,


Event.objects.filter(timeslot__contained_by=period)

# Events which, at least partially, take place during the selected period.
Event.objects.filter(timeslot__overlap=period)

Leggi RangeFields: un gruppo di campi specifici di PostgreSQL online:


https://riptutorial.com/it/django/topic/2630/rangefields--un-gruppo-di-campi-specifici-di-postgresql

https://riptutorial.com/it/home 143
Capitolo 36: Registrazione
Examples
Accesso al servizio Syslog

È possibile configurare Django per l'output del log su un servizio syslog locale o remoto. Questa
configurazione utilizza il python integrato SysLogHandler .

from logging.handlers import SysLogHandler


LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'formatters': {
'standard': {
'format' : "[YOUR PROJECT NAME] [%(asctime)s] %(levelname)s [%(name)s:%(lineno)s]
%(message)s",
'datefmt' : "%d/%b/%Y %H:%M:%S"
}
},
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
'syslog': {
'class': 'logging.handlers.SysLogHandler',
'formatter': 'standard',
'facility': 'user',
# uncomment next line if rsyslog works with unix socket only (UDP reception
disabled)
#'address': '/dev/log'
}
},
'loggers': {
'django':{
'handlers': ['syslog'],
'level': 'INFO',
'disabled': False,
'propagate': True
}
}
}

# loggers for my apps, uses INSTALLED_APPS in settings


# each app must have a configured logger
# level can be changed as desired: DEBUG, INFO, WARNING...
MY_LOGGERS = {}
for app in INSTALLED_APPS:
MY_LOGGERS[app] = {
'handlers': ['syslog'],
'level': 'DEBUG',
'propagate': True,
}
LOGGING['loggers'].update(MY_LOGGERS)

https://riptutorial.com/it/home 144
Configurazione di registrazione di base di Django

Django utilizza internamente il sistema di registrazione Python. Vi sono molti modi per configurare
la registrazione di un progetto. Ecco una base:

LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'default': {
'format': "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s",
'datefmt': "%Y-%m-%d %H:%M:%S"
},
},
'handlers': {
'console': {
'level': 'INFO',
'class': 'logging.StreamHandler',
'formatter': 'default'
},
},
'loggers': {
'django': {
'handlers': ['console'],
'propagate': True,
'level': 'INFO',
},
}
}

formattatori

Può essere utilizzato per configurare l'aspetto dei registri quando vengono stampati sull'output. È
possibile definire molti formattatori impostando una stringa chiave su ogni formattatore diverso. Un
formattatore viene quindi utilizzato quando si dichiara un gestore.

handlers

Può essere usato per configurare dove verranno stampati i registri. Nell'esempio sopra, vengono
inviati a stdout e stderr. Esistono varie classi di gestori:

'rotated_logs': {
'class': 'logging.handlers.RotatingFileHandler',
'filename': '/var/log/my_project.log',
'maxBytes': 1024 * 1024 * 5, # 5 MB
'backupCount': 5,
'formatter': 'default'
'level': 'DEBUG',
},

Ciò produrrà i file di registro immessi per filename . In questo esempio, verrà creato un nuovo file
di registro quando il corrente raggiunge la dimensione di 5 MB (il vecchio viene rinominato in
my_project.log.1) e gli ultimi 5 file verranno conservati per l'archiviazione.

https://riptutorial.com/it/home 145
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler'
},

Questo invierà ciascun log da eamil agli utenti specificati nella variabile di impostazione ADMINS . Il
livello è impostato su ERROR , quindi solo i log con livello ERROR verranno inviati via e-mail. Questo è
estremamente utile per rimanere informati su potenziali errori 50x su un server di produzione.

Altri gestori possono essere utilizzati con Django. Per un elenco completo, leggere la
documentazione corrispondente. Come i formattatori, è possibile definire molti gestori in uno
stesso progetto, impostando per ciascuno una stringa di chiavi diversa. Ogni gestore può essere
utilizzato in un logger specifico.

logger

In LOGGING , l'ultima parte configura per ciascun modulo il livello minimo di registrazione, i gestori da
utilizzare, ecc.

Leggi Registrazione online: https://riptutorial.com/it/django/topic/1231/registrazione

https://riptutorial.com/it/home 146
Capitolo 37: Relazioni molti-a-molti
Examples
Con un modello passante

class Skill(models.Model):
name = models.CharField(max_length=50)
description = models.TextField()

class Developer(models.Model):
name = models.CharField(max_length=50)
skills = models.ManyToManyField(Skill, through='DeveloperSkill')

class DeveloperSkill(models.Model):
"""Developer skills with respective ability and experience."""

class Meta:
order_with_respect_to = 'developer'
"""Sort skills per developer so that he can choose which
skills to display on top for instance.
"""
unique_together = [
('developer', 'skill'),
]
"""It's recommended that a together unique index be created on
`(developer,skill)`. This is especially useful if your database is
being access/modified from outside django. You will find that such an
index is created by django when an explicit through model is not
being used.
"""

ABILITY_CHOICES = [
(1, "Beginner"),
(2, "Accustomed"),
(3, "Intermediate"),
(4, "Strong knowledge"),
(5, "Expert"),
]

developer = models.ForeignKey(Developer, models.CASCADE)


skill = models.ForeignKey(Skill, models.CASCADE)
"""The many-to-many relation between both models is made by the
above two foreign keys.

Other fields (below) store information about the relation itself.


"""

ability = models.PositiveSmallIntegerField(choices=ABILITY_CHOICES)
experience = models.PositiveSmallIntegerField(help_text="Years of experience.")

Si consiglia di creare un indice univoco su (developer,skill) . Questo è particolarmente utile se il


tuo database è accessibile / modificato da un altro django. Troverete che tale indice è creato da
Django quando non viene utilizzato un modello esplicito tramite.

https://riptutorial.com/it/home 147
Relazione semplice da molti a molti.

class Person(models.Model):
name = models.CharField(max_length=50)
description = models.TextField()

class Club(models.Model):
name = models.CharField(max_length=50)
members = models.ManyToManyField(Person)

Qui definiamo una relazione in cui un club ha molte Person e membri e una persona può essere
membro di diversi Club .

Sebbene definiamo solo due modelli, django crea effettivamente tre tabelle nel database per noi.
Questi sono myapp_person , myapp_club e myapp_club_members. Django crea automaticamente un
indice univoco sulle myapp_club_members(club_id,person_id) .

Usando ManyToMany Fields

Usiamo questo modello dal primo esempio:

class Person(models.Model):
name = models.CharField(max_length=50)
description = models.TextField()

class Club(models.Model):
name = models.CharField(max_length=50)
members = models.ManyToManyField(Person)

Aggiungi Tom e Bill al Nightclub:

tom = Person.objects.create(name="Tom", description="A nice guy")


bill = Person.objects.create(name="Bill", description="Good dancer")

nightclub = Club.objects.create(name="The Saturday Night Club")


nightclub.members.add(tom, bill)

Chi è nel club?

for person in nightclub.members.all():


print(person.name)

Ti darò

Tom
Bill

Leggi Relazioni molti-a-molti online: https://riptutorial.com/it/django/topic/2379/relazioni-molti-a-


molti

https://riptutorial.com/it/home 148
Capitolo 38: Riferimento del campo del
modello
Parametri

Parametro Dettagli

Se vero, i valori vuoti possono essere memorizzati come null nel


nullo
database

Se è vero, il campo non sarà richiesto nei moduli. Se i campi vengono


vuoto
lasciati vuoti, Django utilizzerà il valore di campo predefinito.

Un iterable di iterables a 2 elementi da utilizzare come scelte per questo


campo. Se impostato, il campo viene visualizzato come un elenco a
scelte discesa nell'amministratore. [('m', 'Male'),('f','Female'),('z','Prefer
Not to Disclose')] . Per raggruppare le opzioni, annidare semplicemente
i valori: [('Video Source',((1,'YouTube'),(2,'Facebook')),('Audio
Source',((3, 'Soundcloud'),(4, 'Spotify'))]

Per impostazione predefinita, django utilizza il nome del campo per la


db_column
colonna del database. Usalo per fornire un nome personalizzato

db_index Se True , verrà creato un indice su questo campo nel database

Lo spazio tabella da utilizzare per l'indice di questo campo. Questo


db_tablespace campo viene utilizzato solo se il motore del database lo supporta,
altrimenti viene ignorato .

Il valore predefinito per questo campo. Può essere un valore o un


oggetto callable. Per i valori predefiniti mutabili (una lista, un set, un
predefinito
dizionario) devi usare un callable. A causa della compatibilità con le
migrazioni, non è possibile utilizzare lambda.

Se False , il campo non viene mostrato ModelForm del modello o in


modificabile
ModelForm . L'impostazione predefinita è True .

Utilizzato per personalizzare i messaggi di errore predefiniti visualizzati


per questo campo. Il valore è un dizionario, con le chiavi che
messaggio di rappresentano l'errore e il valore è il messaggio. Le chiavi predefinite
errore (per i messaggi di errore) sono null , blank , invalid , invalid_choice ,
unique e unique_for_date ; ulteriori messaggi di errore possono essere
definiti da campi personalizzati.

Testo da visualizzare con il campo, per assistere gli utenti. HTML è


Testo guida
permesso.

https://riptutorial.com/it/home 149
Parametro Dettagli

Quando viene eliminato un oggetto a cui fa riferimento un ForeignKey,


Django emula il comportamento del vincolo SQL specificato
on_delete dall'argomento on_delete. Questo è il secondo argomento posizionale
per i campi ForeignKey e OneToOneField . Altri campi non hanno questo
argomento.

Se True , questo campo sarà la chiave primaria. Django aggiunge


automaticamente una chiave primaria; quindi questo è richiesto solo se
chiave primaria
si desidera creare una chiave primaria personalizzata. Puoi avere solo
una chiave primaria per modello.

Se True , gli errori vengono generati se vengono immessi valori duplicati


unico per questo campo. Questa è una restrizione a livello di database e non
semplicemente un blocco dell'interfaccia utente.

Impostare il valore su DateField o DateTimeField e gli errori verranno


unique_for_date
DateField se vi sono valori duplicati per la stessa data o la stessa data .

unique_for_month Simile a unique_for_date , tranne che i controlli sono limitati per il mese.

unique_for_year Simile a unique_for_date , tranne che i controlli sono limitati all'anno.

Un nome descrittivo per il campo, utilizzato da Django in vari luoghi


verbose_name (come la creazione di etichette nei moduli di amministrazione e di
modello).

validatori Un elenco di validatori per questo campo.

Osservazioni
• Puoi scrivere i tuoi campi se lo ritieni necessario
• È possibile sovrascrivere le funzioni della classe del modello di base, più comunemente la
funzione save()

Examples
Campi numerici

Esempi di campi numerici sono dati:

AutoField

Un numero intero a incremento automatico generalmente utilizzato per le chiavi primarie.

from django.db import models

https://riptutorial.com/it/home 150
class MyModel(models.Model):
pk = models.AutoField()

Per impostazione predefinita, ogni modello riceve un campo chiave primaria (chiamato
id ). Pertanto, non è necessario duplicare un campo id nel modello ai fini di una chiave
primaria.

BigIntegerField

Un numero intero con numeri da -9223372036854775808 a 9223372036854775807 ( 8 Bytes ).

from django.db import models

class MyModel(models.Model):
number_of_seconds = models.BigIntegerField()

IntegerField

IntegerField viene utilizzato per memorizzare valori interi da -2147483648 a 2147483647 ( 4 Bytes
).

from django.db import models

class Food(models.Model):
name = models.CharField(max_length=255)
calorie = models.IntegerField(default=0)

default parametro default non è obbligatorio. Ma è utile impostare un valore


predefinito.

PositiveIntegerField

Come un campo intero, ma deve essere positivo o uguale a zero (0). Il campo PositiveInteger
viene utilizzato per memorizzare valori interi da 0 a 2147483647 ( 4 Bytes ). Questo può essere
utile in campo che dovrebbe essere semanticamente positivo. Ad esempio se stai registrando cibi
con le sue calorie, non dovrebbe essere negativo. Questo campo impedisce i valori negativi
tramite le sue convalide.

from django.db import models

class Food(models.Model):
name = models.CharField(max_length=255)
calorie = models.PositiveIntegerField(default=0)

default parametro default non è obbligatorio. Ma è utile impostare un valore


predefinito.

https://riptutorial.com/it/home 151
SmallIntegerField

SmallIntegerField viene utilizzato per memorizzare valori interi da -32768 a 32767 ( 2 Bytes ).
Questo campo è utile per valori non non estremi.

from django.db import models

class Place(models.Model):
name = models.CharField(max_length=255)
temperature = models.SmallIntegerField(null=True)

PositiveSmallIntegerField

SmallIntegerField viene utilizzato per memorizzare valori interi da 0 a 32767 ( 2 Bytes ). Proprio
come SmallIntegerField questo campo è utile per valori che non vanno così alti e dovrebbero
essere semanticamente positivi. Ad esempio, può memorizzare l'età che non può essere negativa.

from django.db import models

class Staff(models.Model):
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
age = models.PositiveSmallIntegerField(null=True)

Oltre a PositiveSmallIntegerField è utile per le scelte, questo è il modo Djangoic di implementare


Enum:

from django.db import models


from django.utils.translation import gettext as _

APPLICATION_NEW = 1
APPLICATION_RECEIVED = 2
APPLICATION_APPROVED = 3
APPLICATION_REJECTED = 4

APLICATION_CHOICES = (
(APPLICATION_NEW, _('New')),
(APPLICATION_RECEIVED, _('Received')),
(APPLICATION_APPROVED, _('Approved')),
(APPLICATION_REJECTED, _('Rejected')),
)

class JobApplication(models.Model):
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
status = models.PositiveSmallIntegerField(
choices=APLICATION_CHOICES,
default=APPLICATION_NEW
)
...

La definizione delle scelte come variabili di classe o variabili del modulo in base alla
situazione è un buon modo per usarle. Se le scelte sono passate al campo senza nomi
amiche di quanto creerà confusione.

https://riptutorial.com/it/home 152
DecimalField

Un numero decimale a precisione fissa, rappresentato in Python da un'istanza decimale. A


differenza di IntegerField e dei suoi derivati questo campo ha 2 argomenti richiesti:

1. DecimalField.max_digits : il numero massimo di cifre consentito nel numero. Si noti che


questo numero deve essere maggiore o uguale a decimal_places.
2. DecimalField.decimal_places : il numero di posizioni decimali da memorizzare con il numero.

Se si desidera memorizzare numeri fino a 99 con 3 posizioni decimali, è necessario utilizzare


max_digits=5 e decimal_places=3 :

class Place(models.Model):
name = models.CharField(max_length=255)
atmospheric_pressure = models.DecimalField(max_digits=5, decimal_places=3)

BinaryField

Questo è un campo specializzato, usato per memorizzare dati binari. Accetta solo byte . I dati
sono serializzati in base64 su storage.

Poiché si stanno memorizzando dati binari, questo campo non può essere utilizzato in un filtro.

from django.db import models

class MyModel(models.Model):
my_binary_data = models.BinaryField()

CharField

Il CharField viene utilizzato per memorizzare lunghezze di testo definite. Nell'esempio seguente
possono essere memorizzati fino a 128 caratteri di testo nel campo. L'inserimento di una stringa
più lunga comporterà l'innalzamento di un errore di convalida.

from django.db import models

class MyModel(models.Model):
name = models.CharField(max_length=128, blank=True)

DateTimeField

DateTimeField viene utilizzato per memorizzare i valori di data e ora.

class MyModel(models.Model):
start_time = models.DateFimeField(null=True, blank=True)
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)

Un DateTimeField ha due parametri facoltativi:

https://riptutorial.com/it/home 153
• auto_now_add imposta il valore del campo sul datetime corrente al momento della creazione
dell'oggetto.

• auto_now imposta il valore del campo sul datetime corrente ogni volta che viene salvato il
campo.

Queste opzioni e il parametro default si escludono a vicenda.

ForeignKey

Il campo ForeignKey viene utilizzato per creare una relazione many-to-one tra i modelli. Non come
la maggior parte degli altri campi richiede argomenti posizionali. L'esempio seguente dimostra la
relazione tra auto e proprietario:

from django.db import models

class Person(models.Model):
GENDER_FEMALE = 'F'
GENDER_MALE = 'M'

GENDER_CHOICES = (
(GENDER_FEMALE, 'Female'),
(GENDER_MALE, 'Male'),
)

first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
age = models.SmallIntegerField()

class Car(model.Model)
owner = models.ForeignKey('Person')
plate = models.CharField(max_length=15)
brand = models.CharField(max_length=50)
model = models.CharField(max_length=50)
color = models.CharField(max_length=50)

Il primo argomento del campo è la classe a cui è correlato il modello. Il secondo argomento
posizionale è on_delete argomento on_delete . Nelle versioni attuali questo argomento non è
richiesto, ma sarà richiesto in Django 2.0. La funzionalità predefinita dell'argomento è mostrata
come segue:

class Car(model.Model)
owner = models.ForeignKey('Person', on_delete=models.CASCADE)
...

Ciò causerà l'eliminazione degli oggetti Car dal modello quando il relativo proprietario
viene eliminato dal modello Persona. Questa è la funzionalità predefinita.

class Car(model.Model)
owner = models.ForeignKey('Person', on_delete=models.PROTECT)
...

https://riptutorial.com/it/home 154
Ciò impedirà l'eliminazione degli oggetti Person se sono collegati ad almeno un
oggetto Car. Tutti gli oggetti Car che fanno riferimento a un oggetto Persona devono
essere prima eliminati. E poi l'oggetto Persona può essere cancellato.

Leggi Riferimento del campo del modello online:


https://riptutorial.com/it/django/topic/3686/riferimento-del-campo-del-modello

https://riptutorial.com/it/home 155
Capitolo 39: Router di database
Examples
Aggiunta di un file di routing del database

Per utilizzare più database in Django, specifica ciascuno di essi in settings.py :

DATABASES = {
'default': {
'NAME': 'app_data',
'ENGINE': 'django.db.backends.postgresql',
'USER': 'django_db_user',
'PASSWORD': os.environ['LOCAL_DB_PASSWORD']
},
'users': {
'NAME': 'remote_data',
'ENGINE': 'django.db.backends.mysql',
'HOST': 'remote.host.db',
'USER': 'remote_user',
'PASSWORD': os.environ['REMOTE_DB_PASSWORD']
}
}

Utilizzare un file dbrouters.py per specificare quali modelli devono operare su quali database per
ogni classe di operazione del database, ad esempio per i dati remoti archiviati in remote_data , si
potrebbe desiderare quanto segue:

class DbRouter(object):
"""
A router to control all database operations on models in the
auth application.
"""
def db_for_read(self, model, **hints):
"""
Attempts to read remote models go to remote database.
"""
if model._meta.app_label == 'remote':
return 'remote_data'
return 'app_data'

def db_for_write(self, model, **hints):


"""
Attempts to write remote models go to the remote database.
"""
if model._meta.app_label == 'remote':
return 'remote_data'
return 'app_data'

def allow_relation(self, obj1, obj2, **hints):


"""
Do not allow relations involving the remote database
"""
if obj1._meta.app_label == 'remote' or \

https://riptutorial.com/it/home 156
obj2._meta.app_label == 'remote':
return False
return None

def allow_migrate(self, db, app_label, model_name=None, **hints):


"""
Do not allow migrations on the remote database
"""
if model._meta.app_label == 'remote':
return False
return True

Infine, aggiungi il tuo dbrouter.py a settings.py :

DATABASE_ROUTERS = ['path.to.DbRouter', ]

Specifica di diversi database nel codice

Il normale metodo obj.save() utilizzerà il database predefinito oppure, se viene utilizzato un router
di database, utilizzerà il database come specificato in db_for_write . Puoi sovrascriverlo usando:

obj.save(using='other_db')
obj.delete(using='other_db')

Allo stesso modo, per la lettura:

MyModel.objects.using('other_db').all()

Leggi Router di database online: https://riptutorial.com/it/django/topic/3395/router-di-database

https://riptutorial.com/it/home 157
Capitolo 40: Routing URL
Examples
Come Django gestisce una richiesta

Django gestisce una richiesta instradando il percorso dell'URL in entrata a una funzione di
visualizzazione. La funzione di visualizzazione è responsabile di restituire una risposta al client
che effettua la richiesta. URL diversi vengono generalmente gestiti da diverse funzioni di
visualizzazione. Per indirizzare la richiesta ad una specifica funzione di visualizzazione, Django
controlla la configurazione dell'URL (o URLconf in breve). Il modello di progetto predefinito
definisce URLconf in <myproject>/urls.py .

Il tuo URLconf dovrebbe essere un modulo python che definisce un attributo chiamato urlpatterns
, che è una lista di django.conf.urls.url() di django.conf.urls.url() . Ogni istanza di url() deve
almeno definire un'espressione regolare (una regex) da abbinare all'URL e una destinazione, che
è una funzione di visualizzazione o un URLconf differente. Se un pattern URL ha come target una
funzione di visualizzazione, è una buona idea assegnargli un nome per fare facilmente riferimento
al modello in un secondo momento.

Diamo un'occhiata a un esempio di base:

# In <myproject>/urls.py

from django.conf.urls import url

from myapp.views import home, about, blog_detail

urlpatterns = [
url(r'^$', home, name='home'),
url(r'^about/$', about, name='about'),
url(r'^blog/(?P<id>\d+)/$', blog_detail, name='blog-detail'),
]

Questo URLconf definisce tre pattern URL, tutti mirati a una vista: home , about e blog-detail .

• url(r'^$', home, name='home'),

La regex contiene un'ancora di inizio '^', immediatamente seguita da un'ancora di fine '$'. Questo
modello corrisponderà alle richieste in cui il percorso dell'URL è una stringa vuota e le indirizza
alla vista home definita in myapp.views .

• url(r'^about/$', about, name='about'),

Questa regex contiene un'ancora di inizio, seguita dalla stringa letterale about/ , e dall'ancora di
fine. Questo corrisponderà all'URL /about/ e lo indirizzerà alla visualizzazione about . Poiché ogni
URL non vuoto inizia con un / , Django taglia comodamente la prima barra per te.

• url(r'^blog/(?P<id>\d+)/$', blog_detail, name='blog-detail'),

https://riptutorial.com/it/home 158
Questa regex è un po 'più complessa. Definisce l'ancora di partenza e il blog/ stringa letterale
blog/ , come il modello precedente. La parte successiva, (?P<id>\d+) , è chiamata gruppo di
cattura. Un gruppo che cattura, come suggerisce il nome, cattura una parte della stringa e Django
passa la stringa catturata come argomento alla funzione di visualizzazione.

La sintassi di un gruppo che cattura è (?P<name>pattern) . name definisce il nome del gruppo, che è
anche il nome che Django usa per passare l'argomento alla vista. Il modello definisce quali
caratteri sono abbinati al gruppo.

In questo caso, il nome è id , quindi la funzione blog_detail deve accettare un parametro


denominato id . Il modello è \d+ . \d indica che il modello corrisponde solo ai caratteri numerici. +
significa che il modello deve corrispondere a uno o più caratteri.

Alcuni modelli comuni:

Modello Usato per fiammiferi

\d+ id Uno o più caratteri numerici

[\w-]+ lumaca Uno o più caratteri alfanumerici, trattini bassi o trattini

[0-9]{4} anno (lungo) Quattro numeri, da zero a nove

anno (breve)
[0-9]{2} mese Due numeri, da zero a nove
giorno del mese

[^/]+ segmento del percorso Qualunque cosa tranne una barra

Il gruppo di cattura nel modello di blog-detail del blog-detail è seguito da un letterale / e


dall'ancora finale.

Gli URL validi includono:

• /blog/1/ # passes id='1'


• /blog/42/ # passes id='42'

Gli URL non validi sono ad esempio:

• /blog/a/ # 'a' does not match '\d'


• /blog// # no characters in the capturing group does not match '+'

Django elabora ogni pattern URL nello stesso ordine in cui sono definiti in urlpatterns . Questo è
importante se più pattern possono corrispondere allo stesso URL. Per esempio:

urlpatterns = [
url(r'blog/(?P<slug>[\w-]+)/$', blog_detail, name='blog-detail'),
url(r'blog/overview/$', blog_overview, name='blog-overview'),
]

https://riptutorial.com/it/home 159
Nel precedente URLconf, il secondo modello non è raggiungibile. Lo schema corrisponderebbe
all'URL /blog/overview/ , ma invece di chiamare la vista blog_overview , l'URL corrisponderà
innanzitutto al modello di blog-detail del blog-detail e chiamerà la vista blog_detail con un
argomento slug='overview' .

Per assicurarsi che l'URL /blog/overview/ sia indirizzato alla vista blog_overview , lo schema deve
essere posizionato sopra il modello dei blog-detail del blog-detail :

urlpatterns = [
url(r'blog/overview/$', blog_overview, name='blog-overview'),
url(r'blog/(?P<slug>[\w-]+)/$', blog_detail, name='blog-detail'),
]

Imposta lo spazio dei nomi URL per un'app riutilizzabile (Django 1.9+)

Configura URLconf della tua app per utilizzare automaticamente uno spazio dei nomi URL
impostando l'attributo app_name :

# In <myapp>/urls.py
from django.conf.urls import url

from .views import overview

app_name = 'myapp'
urlpatterns = [
url(r'^$', overview, name='overview'),
]

Questo imposterà lo spazio 'myapp' nomi dell'applicazione su 'myapp' quando è incluso nel root
URLconf>. L'utente della tua app riusabile non deve eseguire alcuna configurazione se non
includere gli URL:

# In <myproject>/urls.py
from django.conf.urls import include, url

urlpatterns = [
url(r'^myapp/', include('myapp.urls')),
]

La tua app riusabile può ora invertire gli URL utilizzando lo spazio dei nomi dell'applicazione:

>>> from django.urls import reverse


>>> reverse('myapp:overview')
'/myapp/overview/'

L'URL rootonf può ancora impostare uno spazio dei namespace dell'istanza con il parametro
namespace :

# In <myproject>/urls.py
urlpatterns = [
url(r'^myapp/', include('myapp.urls', namespace='mynamespace')),

https://riptutorial.com/it/home 160
]

Sia lo spazio dei nomi dell'applicazione che lo spazio dei nomi dell'istanza possono essere
utilizzati per invertire gli URL:

>>> from django.urls import reverse


>>> reverse('myapp:overview')
'/myapp/overview/'
>>> reverse('mynamespace:overview')
'/myapp/overview/'

Il namespace dell'istanza si imposta automaticamente sullo spazio dei nomi dell'applicazione se


non è impostato in modo esplicito.

Leggi Routing URL online: https://riptutorial.com/it/django/topic/3299/routing-url

https://riptutorial.com/it/home 161
Capitolo 41: segnali
Parametri

Classe / Metodo Il perché

UserProfile ()
La classe UserProfile estende il modello utente predefinito Django .
Class

metodo Il metodo create_profile () viene eseguito ogni volta che viene rilasciato
create_profile () un segnale post_save modello utente Django.

Osservazioni
Ora, i dettagli.

I segnali Django sono un modo per informare la tua app di determinati compiti (come un modello
pre o post-salvataggio o eliminazione) quando ha luogo.

Questi segnali ti consentono di eseguire azioni a tua scelta immediatamente che il segnale viene
rilasciato.

Ad esempio, ogni volta che viene creato un nuovo utente Django, il Modello utente rilascia un
segnale, associando parametri come sender=User consente di indirizzare in modo specifico
l'ascolto dei segnali a un'attività specifica che si verifica, in questo caso, una nuova creazione
utente .

Nell'esempio precedente, l'intenzione è di creare un oggetto Profilo utente creato immediatamente


dopo la creazione di un oggetto Utente. Pertanto, ascoltando specificamente un segnale post_save
dal modello User (il modello utente Django predefinito), creiamo un oggetto UserProfile subito
dopo la creazione di un nuovo User .

La documentazione di Django fornisce un'ampia documentazione su tutti i possibili segnali


disponibili .

Tuttavia, l'esempio sopra riportato è quello di spiegare in termini pratici un tipico caso d'uso
quando si usano i segnali come un'aggiunta utile.

"Con un grande potere viene una grande responsabilità". Può essere allettante avere segnali
sparsi per l'intera app o progetto solo perché sono fantastici. Bene, non farlo. Perché sono cool
non li rende la soluzione ideale per ogni situazione semplice che viene in mente.

I segnali sono ottimi, come al solito, non tutto. Login / Logout, i segnali sono fantastici. Modelli
chiave che rilascino segnali, come il Modello utente, se disponibili.

La creazione di segnali per ogni modello della tua app può diventare travolgente a un certo punto

https://riptutorial.com/it/home 162
e sconfiggere l'intera idea dell'uso sparring di Django Signals.

Non usare segnali quando (basato su Two Scoops of Django book ):

• Il segnale si riferisce a un modello particolare e può essere spostato in uno dei metodi di
quel modello, eventualmente chiamato da save() .
• Il segnale può essere sostituito con un metodo di gestione modello personalizzato.
• Il segnale si riferisce a una vista particolare e può essere spostato in quella vista

Potrebbe essere normale usare i segnali quando:

• Il ricevitore del segnale deve apportare modifiche a più di un modello.


• Vuoi inviare lo stesso segnale da più app e farle gestire allo stesso modo da un ricevitore
comune.
• Si desidera invalidare una cache dopo un salvataggio del modello.
• Hai uno scenario insolito che richiede una richiamata e non c'è altro modo per gestirlo oltre a
utilizzare un segnale. Ad esempio, si desidera attivare qualcosa in base al save() o init()
del modello di un'app di terze parti. Non è possibile modificare il codice di terze parti ed
estenderlo potrebbe essere impossibile, quindi un segnale fornisce un trigger per un
callback.

Examples
Estensione dell'esempio del profilo utente

Questo esempio è uno snippet tratto dal profilo utente Django esteso come un Pro

from django.db import models


from django.contrib.auth.models import User
from django.db.models.signals import post_save

class UserProfile(models.Model):
user = models.OneToOneField(User, related_name='user')
website = models.URLField(default='', blank=True)
bio = models.TextField(default='', blank=True)

def create_profile(sender, **kwargs):


user = kwargs["instance"]
if kwargs["created"]:
user_profile = UserProfile(user=user)
user_profile.save()
post_save.connect(create_profile, sender=User)

Sintassi diversa per postare / pre un segnale

from django.db import models


from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver

class UserProfile(models.Model):

https://riptutorial.com/it/home 163
user = models.OneToOneField(User, related_name='user')
website = models.URLField(default='', blank=True)
bio = models.TextField(default='', blank=True)

@receiver(post_save, sender=UserProfile)
def post_save_user(sender, **kwargs):
user = kwargs.get('instance')
if kwargs.get('created'):
...

Come trovare se si tratta di un inserimento o di un aggiornamento nel segnale


pre_save

Utilizzando il pre_save possiamo determinare se un'azione di save sul nostro database riguardava
l'aggiornamento di un oggetto esistente o la creazione di uno nuovo.

Per ottenere ciò è possibile controllare lo stato dell'oggetto modello:

@receiver(pre_save, sender=User)
def pre_save_user(sender, instance, **kwargs):
if not instance._state.adding:
print ('this is an update')
else:
print ('this is an insert')

Ora ogni volta che viene eseguita un'azione di save , il segnale pre_save verrà eseguito e
stamperà:

• this is an update se l'azione deriva da un'azione di aggiornamento.


• this is an insert se l'azione deriva da un'azione di inserimento.

Si noti che questo metodo non richiede query di database aggiuntive.

Ereditare i segnali sui modelli estesi

I segnali di Django sono limitati a precise firme di classe al momento della registrazione, e quindi i
modelli sottoclasse non vengono immediatamente registrati sullo stesso segnale.

Prendi questo modello e segnala per esempio

class Event(models.Model):
user = models.ForeignKey(User)

class StatusChange(Event):
...

class Comment(Event):
...

https://riptutorial.com/it/home 164
def send_activity_notification(sender, instance: Event, raw: bool, **kwargs):
"""
Fire a notification upon saving an event
"""

if not raw:
msg_factory = MessageFactory(instance.id)
msg_factory.on_activity(str(instance))
post_save.connect(send_activity_notification, Event)

Con i modelli estesi, è necessario collegare manualmente il segnale su ciascuna sottoclasse


altrimenti non verranno effettuati.

post_save.connect(send_activity_notification, StatusChange)
post_save.connect(send_activity_notification, Comment)

Con Python 3.6, puoi sfruttare alcuni metodi di classe aggiuntivi incorporati in classi per
automatizzare questa associazione.

class Event(models.Model):

@classmethod
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
post_save.connect(send_activity_notification, cls)

Leggi segnali online: https://riptutorial.com/it/django/topic/2555/segnali

https://riptutorial.com/it/home 165
Capitolo 42: set di query
introduzione
Un Queryset è fondamentalmente un elenco di oggetti derivati da un Model , da una raccolta di
query di database.

Examples
Domande semplici su un modello standalone

Ecco un semplice modello che utilizzeremo per eseguire alcune query di test:

class MyModel(models.Model):
name = models.CharField(max_length=10)
model_num = models.IntegerField()
flag = models.NullBooleanField(default=False)

Ottieni un singolo oggetto modello in cui id / pk è 4:


(Se non ci sono elementi con l'id di 4 o ce ne sono più di uno, questo genererà un'eccezione).

MyModel.objects.get(pk=4)

Tutti gli oggetti del modello:

MyModel.objects.all()

Gli oggetti del modello con flag impostato su True :

MyModel.objects.filter(flag=True)

Oggetti del modello con un numero di model_num maggiore di 25:

MyModel.objects.filter(model_num__gt=25)

Oggetti modello con il name di "Articolo economico" e il flag impostato su False :

MyModel.objects.filter(name="Cheap Item", flag=False)

Modello semplice name ricerca per stringa specifica (sensibile al maiuscolo / minuscolo):

MyModel.objects.filter(name__contains="ch")

Modello semplice name ricerca per stringa specifica (senza distinzione tra maiuscole e minuscole):

https://riptutorial.com/it/home 166
MyModel.objects.filter(name__icontains="ch")

Query avanzate con oggetti Q

Dato il modello:

class MyModel(models.Model):
name = models.CharField(max_length=10)
model_num = models.IntegerField()
flag = models.NullBooleanField(default=False)

Possiamo utilizzare oggetti Q per creare condizioni AND , OR nella query di ricerca. Ad esempio,
supponiamo di volere tutti gli oggetti che hanno flag=True OR model_num>15 .

from django.db.models import Q


MyModel.objects.filter(Q(flag=True) | Q(model_num__gt=15))

Quanto sopra si traduce in WHERE flag=True OR model_num > 15 modo simile per un AND che si
dovrebbe fare.

MyModel.objects.filter(Q(flag=True) & Q(model_num__gt=15))

Q oggetti Q ci permettono anche di fare NOT query con l'uso di ~ . Diciamo che volevamo ottenere
tutti gli oggetti che hanno flag=False AND model_num!=15 , dovremmo fare:

MyModel.objects.filter(Q(flag=True) & ~Q(model_num=15))

Se si utilizzano oggetti Q e parametri "normali" in filter() , gli oggetti Q devono prima venire. La
seguente query cerca i modelli con ( flag impostato su True o un numero di modello maggiore di 15
) e un nome che inizia con "H".

from django.db.models import Q


MyModel.objects.filter(Q(flag=True) | Q(model_num__gt=15), name__startswith="H")

Nota: gli oggetti Q possono essere utilizzati con qualsiasi funzione di ricerca che accetta
argomenti di parole chiave come filter , exclude , get . Assicurati che quando usi con get ,
restituirai un solo oggetto o verrà sollevata l'eccezione MultipleObjectsReturned .

Riduci il numero di query su ManyToManyField (n + 1 problema)

Problema
# models.py:
class Library(models.Model):
name = models.CharField(max_length=100)
books = models.ManyToManyField(Book)

https://riptutorial.com/it/home 167
class Book(models.Model):
title = models.CharField(max_length=100)

# views.py
def myview(request):
# Query the database.
libraries = Library.objects.all()

# Query the database on each iteration (len(author) times)


# if there is 100 librairies, there will have 100 queries plus the initial query
for library in libraries:
books = library.books.all()
books[0].title
# ...

# total : 101 queries

Soluzione
Usa prefetch_related su ManyToManyField se sai che dovrai accedere più tardi a un campo che è un
campo ManyToManyField .

# views.py
def myview(request):
# Query the database.
libraries = Library.objects.prefetch_related('books').all()

# Does not query the database again, since `books` is pre-populated


for library in libraries:
books = library.books.all()
books[0].title
# ...

# total : 2 queries - 1 for libraries, 1 for books

prefetch_related può essere utilizzato anche nei campi di ricerca:

# models.py:
class User(models.Model):
name = models.CharField(max_length=100)

class Library(models.Model):
name = models.CharField(max_length=100)
books = models.ManyToManyField(Book)

class Book(models.Model):
title = models.CharField(max_length=100)
readers = models.ManyToManyField(User)

# views.py
def myview(request):
# Query the database.
libraries = Library.objects.prefetch_related('books', 'books__readers').all()

https://riptutorial.com/it/home 168
# Does not query the database again, since `books` and `readers` is pre-populated
for library in libraries:
for book in library.books.all():
for user in book.readers.all():
user.name
# ...

# total : 3 queries - 1 for libraries, 1 for books, 1 for readers

Tuttavia, una volta eseguito il queryset, i dati recuperati non possono essere modificati senza
colpire nuovamente il database. Il seguente eseguirà query aggiuntive per esempio:

# views.py
def myview(request):
# Query the database.
libraries = Library.objects.prefetch_related('books').all()
for library in libraries:
for book in library.books.filter(title__contains="Django"):
print(book.name)

Quanto segue può essere ottimizzato usando un oggetto Prefetch , introdotto in Django 1.7:

from django.db.models import Prefetch


# views.py
def myview(request):
# Query the database.
libraries = Library.objects.prefetch_related(
Prefetch('books', queryset=Book.objects.filter(title__contains="Django")
).all()
for library in libraries:
for book in library.books.all():
print(book.name) # Will print only books containing Django for each library

Riduci il numero di query sul campo ForeignKey (n + 1 problema)

Problema
I querysets di Django sono valutati in modo pigro. Per esempio:

# models.py:
class Author(models.Model):
name = models.CharField(max_length=100)

class Book(models.Model):
author = models.ForeignKey(Author, related_name='books')
title = models.CharField(max_length=100)

# views.py
def myview(request):
# Query the database
books = Book.objects.all()

for book in books:

https://riptutorial.com/it/home 169
# Query the database on each iteration to get author (len(books) times)
# if there is 100 books, there will have 100 queries plus the initial query
book.author
# ...

# total : 101 queries

Il codice sopra fa in modo che django interroghi il database per l'autore di ogni libro. Questo è
inefficiente ed è meglio avere una sola query.

Soluzione
Usa select_related su ForeignKey se sai che dovrai accedere successivamente a un campo
ForeignKey .

# views.py
def myview(request):
# Query the database.
books = Books.objects.select_related('author').all()

for book in books:


# Does not query the database again, since `author` is pre-populated
book.author
# ...

# total : 1 query

select_related può essere utilizzato anche nei campi di ricerca:

# models.py:
class AuthorProfile(models.Model):
city = models.CharField(max_length=100)

class Author(models.Model):
name = models.CharField(max_length=100)
profile = models.OneToOneField(AuthorProfile)

class Book(models.Model):
author = models.ForeignKey(Author, related_name='books')
title = models.CharField(max_length=100)

# views.py
def myview(request):
books = Book.objects.select_related('author')\
.select_related('author__profile').all()

for book in books:


# Does not query database
book.author.name
# or
book.author.profile.city
# ...

# total : 1 query

https://riptutorial.com/it/home 170
Ottieni SQL per il queryset di Django

L'attributo query su queryset fornisce una sintassi equivalente SQL per la query.

>>> queryset = MyModel.objects.all()


>>> print(queryset.query)
SELECT "myapp_mymodel"."id", ... FROM "myapp_mymodel"

Avvertimento:

Questo output dovrebbe essere utilizzato solo a scopo di debug. La query generata
non è specifica per il back-end. Di conseguenza, i parametri non vengono citati
correttamente, lasciandoli vulnerabili all'iniezione SQL e la query potrebbe non essere
nemmeno eseguibile sul back-end del database.

Ottieni il primo e l'ultimo record da QuerySet

Per ottenere il primo oggetto:

MyModel.objects.first()

Per ottenere gli ultimi oggetti:

MyModel.objects.last()

Usando il filtro Primo oggetto:

MyModel.objects.filter(name='simple').first()

Utilizzo del filtro Ultimo oggetto:

MyModel.objects.filter(name='simple').last()

Query avanzate con oggetti F

Un oggetto F () rappresenta il valore di un campo modello o di una colonna annotata.


Permette di fare riferimento ai valori dei campi del modello ed eseguire operazioni di
database che li utilizzano senza doverli estrarre dal database in memoria Python. - F ()
espressioni

È opportuno utilizzare oggetti F() ogni volta che è necessario fare riferimento al valore di un altro
campo nella query. Di per sé, gli oggetti F() non significano nulla, e non possono e non devono
essere chiamati al di fuori di un queryset. Sono usati per fare riferimento al valore di un campo
sullo stesso queryset.

Ad esempio, dato un modello ...

https://riptutorial.com/it/home 171
SomeModel(models.Model):
...
some_field = models.IntegerField()

... un utente può interrogare oggetti in cui il valore some_field è il doppio del suo id facendo
riferimento al valore del campo id mentre si filtra usando F() come questo:

SomeModel.objects.filter(some_field=F('id') * 2)

F('id') semplicemente riferimento al valore id per quella stessa istanza. Django lo usa per creare
un'istruzione SQL corrispondente. In questo caso qualcosa di simile a questo:

SELECT * FROM some_app_some_model


WHERE some_field = ((id * 2))

Senza le espressioni F() ciò sarebbe possibile con SQL raw o filtro in Python (che riduce le
prestazioni soprattutto quando ci sono molti oggetti).

Riferimenti:

• I filtri possono fare riferimento ai campi sul modello


• Espressioni F
• Risposta da TinyInstance

Dalla definizione della classe F() :

Un oggetto in grado di risolvere i riferimenti a oggetti di query esistenti. - F fonte

Nota: questo esempio pubblicato proviene dalla risposta sopra elencata con il consenso di
TinyInstance.

Leggi set di query online: https://riptutorial.com/it/django/topic/1235/set-di-query

https://riptutorial.com/it/home 172
Capitolo 43: Sicurezza
Examples
Protezione Cross Site Scripting (XSS)

Gli attacchi XSS consistono nell'iniettare codice HTML (o JS) in una pagina. Vedi Che cos'è cross-
site scripting per ulteriori informazioni.

Per evitare questo attacco, per impostazione predefinita, Django sfugge alle stringhe passate
attraverso una variabile di modello.

Dato il seguente contesto:

context = {
'class_name': 'large" style="font-size:4000px',
'paragraph': (
"<script type=\"text/javascript\">alert('hello world!');</script>"),
}

<p class="{{ class_name }}">{{ paragraph }}</p>


<!-- Will be rendered as: -->
<p class="large&quot; style=&quot;font-size: 4000px">&lt;script&gt;alert(&#39;hello
world!&#39;);&lt;/script&gt;</p>

Se hai delle variabili contenenti HTML di cui ti fidi e in realtà vuoi eseguire il rendering, devi dire
esplicitamente che è sicuro:

<p class="{{ class_name|safe }}">{{ paragraph }}</p>


<!-- Will be rendered as: -->
<p class="large" style="font-size: 4000px">&lt;script&gt;alert(&#39;hello
world!&#39;);&lt;/script&gt;</p>

Se hai un blocco contenente più variabili che sono tutte sicure, puoi disabilitare localmente
l'escape automatico:

{% autoescape off %}
<p class="{{ class_name }}">{{ paragraph }}</p>
{% endautoescape %}
<!-- Will be rendered as: -->
<p class="large" style="font-size: 4000px"><script>alert('hello world!');</script></p>

Puoi anche contrassegnare una stringa come sicura al di fuori del modello:

from django.utils.safestring import mark_safe

context = {
'class_name': 'large" style="font-size:4000px',
'paragraph': mark_safe(
"<script type=\"text/javascript\">alert('hello world!');</script>"),

https://riptutorial.com/it/home 173
}

<p class="{{ class_name }}">{{ paragraph }}</p>


<!-- Will be rendered as: -->
<p class="large&quot; style=&quot;font-size: 4000px"><script>alert('hello
world!');</script></p>

Alcune utilità Django come format_html restituiscono già stringhe contrassegnate come sicure:

from django.utils.html import format_html

context = {
'var': format_html('<b>{}</b> {}', 'hello', '<i>world!</i>'),
}

<p>{{ var }}</p>


<!-- Will be rendered as -->
<p><b>hello</b> &lt;i&gt;world!&lt;/i&gt;</p>

Protezione da Clickjacking

Il clickjacking è una tecnica dannosa di ingannare un utente Web per fare clic su
qualcosa di diverso da ciò che l'utente percepisce su cui sta facendo clic. Per saperne
di più

Per abilitare la protezione da clickjacking, aggiungi XFrameOptionsMiddleware alle tue classi


middleware. Questo dovrebbe già essere lì se non lo hai rimosso.

# settings.py
MIDDLEWARE_CLASSES = [
...
'django.middleware.clickjacking.XFrameOptionsMiddleware',
...
]

Questo middleware imposta l'intestazione 'X-Frame-Options' su tutte le tue risposte, a meno che
non sia esplicitamente esentato o impostato (non sovrascritto se già impostato nella risposta). Di
default è impostato su "SAMEORIGIN". Per cambiare questo, usa l'impostazione X_FRAME_OPTIONS :

X_FRAME_OPTIONS = 'DENY'

È possibile sovrascrivere il comportamento predefinito su base per visualizzazione.

from django.utils.decorators import method_decorator


from django.views.decorators.clickjacking import (
xframe_options_exempt, xframe_options_deny, xframe_options_sameorigin,
)

xframe_options_exempt_m = method_decorator(xframe_options_exempt, name='dispatch')

@xframe_options_sameorigin
def my_view(request, *args, **kwargs):

https://riptutorial.com/it/home 174
"""Forces 'X-Frame-Options: SAMEORIGIN'."""
return HttpResponse(...)

@method_decorator(xframe_options_deny, name='dispatch')
class MyView(View):
"""Forces 'X-Frame-Options: DENY'."""

@xframe_options_exempt_m
class MyView(View):
"""Does not set 'X-Frame-Options' header when passing through the
XFrameOptionsMiddleware.
"""

Protezione da richiesta di cross-site Forgery (CSRF)

La falsificazione della richiesta tra siti, anche nota come attacco con un clic o sessione
in corso e abbreviata come CSRF o XSRF, è un tipo di exploit dannoso di un sito Web
in cui vengono trasmessi comandi non autorizzati da un utente ritenuto affidabile dal
sito Web. Per saperne di più

Per abilitare la protezione CSRF, aggiungi CsrfViewMiddleware alle tue classi middleware. Questo
middleware è abilitato per impostazione predefinita.

# settings.py
MIDDLEWARE_CLASSES = [
...
'django.middleware.csrf.CsrfViewMiddleware',
...
]

Questo middleware imposterà un token in un cookie sulla risposta in uscita. Ogni volta che una
richiesta in entrata utilizza un metodo non sicuro (qualsiasi metodo tranne GET , HEAD , OPTIONS e
TRACE ), il cookie deve corrispondere a un token che viene inviato come dati del modulo
csrfmiddlewaretoken o come intestazione X-CsrfToken . Ciò garantisce che il client che avvia la
richiesta sia anche il proprietario del cookie e, per estensione, la sessione (autenticata).

Se viene eseguita una richiesta su HTTPS , il controllo referrer rigoroso è abilitato. Se l'intestazione
HTTP_REFERER non corrisponde all'host della richiesta corrente o di un host in CSRF_TRUSTED_ORIGINS (
novità in 1.9 ), la richiesta viene respinta.

I moduli che utilizzano il metodo POST devono includere il token CSRF nel modello. Il tag del
modello {% csrf_token %} un campo nascosto e garantisce che il cookie sia impostato sulla
risposta:

<form method='POST'>
{% csrf_token %}
...
</form>

Le singole viste che non sono vulnerabili agli attacchi CSRF possono essere rese esenti
utilizzando il decoratore @csrf_exempt :

https://riptutorial.com/it/home 175
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def my_view(request, *args, **kwargs):
"""Allows unsafe methods without CSRF protection"""
return HttpResponse(...)

Sebbene non sia raccomandato, è possibile disabilitare CsrfViewMiddleware se molte delle viste non
sono vulnerabili agli attacchi CSRF. In questo caso puoi utilizzare il decoratore @csrf_protect per
proteggere le singole visualizzazioni:

from django.views.decorators.csrf import csrf_protect

@csrf_protect
def my_view(request, *args, **kwargs):
"""This view is protected against CSRF attacks if the middleware is disabled"""
return HttpResponse(...)

Leggi Sicurezza online: https://riptutorial.com/it/django/topic/2957/sicurezza

https://riptutorial.com/it/home 176
Capitolo 44: Struttura del progetto
Examples
Deposito> Progetto> Sito / Conf

Per un progetto Django con requirements e deployment tools sotto il controllo del codice sorgente.
Questo esempio si basa su concetti tratti dai due scoop di Django . Hanno pubblicato un modello :

repository/
docs/
.gitignore
project/
apps/
blog/
migrations/
static/ #( optional )
blog/
some.css
templates/ #( optional )
blog/
some.html
models.py
tests.py
admin.py
apps.py #( django 1.9 and later )
views.py
accounts/
#... ( same as blog )
search/
#... ( same as blog )
conf/
settings/
local.py
development.py
production.py
wsgi
urls.py
static/
templates/
deploy/
fabfile.py
requirements/
base.txt
local.txt
README
AUTHORS
LICENSE

Qui le apps e le cartelle conf contengono rispettivamente user created applications e la core
configuration folder per il progetto.

static cartelle static e di templates nella directory del project contengono rispettivamente file
statici e file html markup che vengono utilizzati globalmente in tutto il progetto.

https://riptutorial.com/it/home 177
E tutte le cartelle di app blog , accounts e search possono anche (principalmente) contenere cartelle
static e templates .

Namespacing statico e file di modelli in applicazioni django

static cartella static e di templates nelle app potrebbe anche contenere una cartella con il nome
dell'app ex. blog questa è una convenzione usata per prevenire l'inquinamento dello spazio dei
nomi, quindi facciamo riferimento ai file come /blog/base.html piuttosto che /base.html che fornisce
maggiore chiarezza sul file a cui stiamo facendo riferimento e mantiene lo spazio dei nomi.

Esempio: la cartella dei templates all'interno del blog e delle applicazioni di search contiene un file
con nome base.html e quando si fa riferimento al file nelle views l'applicazione viene confusa in
quale file eseguire il rendering.

(Project Structure)
.../project/
apps/
blog/
templates/
base.html
search/
templates/
base.html

(blog/views.py)
def some_func(request):
return render(request, "/base.html")

(search/views.py)
def some_func(request):
return render(request, "/base.html")

## After creating a folder inside /blog/templates/(blog) ##

(Project Structure)
.../project/
apps/
blog/
templates/
blog/
base.html
search/
templates/
search/
base.html

(blog/views.py)
def some_func(request):
return render(request, "/blog/base.html")

(search/views.py)
def some_func(request):
return render(request, "/search/base.html")

Leggi Struttura del progetto online: https://riptutorial.com/it/django/topic/4299/struttura-del-progetto

https://riptutorial.com/it/home 178
Capitolo 45: Tag e filtri modello
Examples
Filtri personalizzati

Filtri consente di applicare una funzione a una variabile. Questa funzione può richiedere 0 o 1
argomento. Ecco la sintassi:

{{ variable|filter_name }}
{{ variable|filter_name:argument }}

I filtri possono essere concatenati, quindi questo è perfettamente valido:

{{ variable|filter_name:argument|another_filter }}

Se tradotto in python la riga precedente darebbe qualcosa di simile a questo:

print(another_filter(filter_name(variable, argument)))

In questo esempio, scriveremo un filtro personalizzato verbose_name che si applica a un modello


(istanza o classe) oa un oggetto QuerySet. Restituirà il nome dettagliato di un modello o il suo
nome prolisso plurale se l'argomento è impostato su True .

@register.filter
def verbose_name(model, plural=False):
"""Return the verbose name of a model.
`model` can be either:
- a Model class
- a Model instance
- a QuerySet
- any object refering to a model through a `model` attribute.

Usage:
- Get the verbose name of an object
{{ object|verbose_name }}
- Get the plural verbose name of an object from a QuerySet
{{ objects_list|verbose_name:True }}
"""
if not hasattr(model, '_meta'):
# handle the case of a QuerySet (among others)
model = model.model
opts = model._meta
if plural:
return opts.verbose_name_plural
else:
return opts.verbose_name

Tag semplici

https://riptutorial.com/it/home 179
Il modo più semplice per definire un tag modello personalizzato è utilizzare un simple_tag . Questi
sono molto semplici da configurare. Il nome della funzione sarà il nome del tag (sebbene sia
possibile sovrascriverlo) e gli argomenti saranno token ("parole" separati da spazi, ad eccezione
degli spazi racchiusi tra virgolette). Supporta anche argomenti di parole chiave.

Ecco un tag inutile che illustrerà il nostro esempio:

{% useless 3 foo 'hello world' foo=True bar=baz.hello|capfirst %}

Lascia che foo e baz siano variabili di contesto come la seguente:

{'foo': "HELLO", 'baz': {'hello': "world"}}

Diciamo che vogliamo questo tag molto inutile per renderizzare in questo modo:

HELLO;hello world;bar:World;foo:True<br/>
HELLO;hello world;bar:World;foo:True<br/>
HELLO;hello world;bar:World;foo:True<br/>

Tipo di concatenazione degli argomenti ripetuta 3 volte (3 è il primo argomento).

Ecco come può essere l'implementazione del tag:

from django.utils.html import format_html_join

@register.simple_tag
def useless(repeat, *args, **kwargs):
output = ';'.join(args + ['{}:{}'.format(*item) for item in kwargs.items()])
outputs = [output] * repeat
return format_html_join('\n', '{}<br/>', ((e,) for e in outputs))

format_html_join consente di contrassegnare <br/> come HTML sicuro, ma non il contenuto delle
outputs .

Tag personalizzati avanzati usando il nodo

A volte ciò che vuoi fare è troppo complesso per un filter o un semplice simple_tag . Fow questo
è necessario creare una funzione di compilazione e un renderer.

In questo esempio creeremo un tag template verbose_name con la seguente sintassi:

Esempio Descrizione

{% verbose_name obj %} Nome dettagliato di un modello

{% verbose_name obj 'status' %} Nome dettagliato del campo "stato"

{% verbose_name obj plural %} Nome prolisso plurale di un modello

{% verbose_name obj plural capfirst %} Nome dettagliato in maiuscolo plurale di un

https://riptutorial.com/it/home 180
Esempio Descrizione

modello

{% verbose_name obj 'foo' capfirst %} Nome dettagliato in maiuscolo di un campo

{% verbose_name obj field_name %} Nome dettagliato di un campo da una variabile

{% verbose_name obj 'foo'|add:'_bar'


%} Nome dettagliato di un campo "foo_bar"

Il motivo per cui non possiamo farlo con un semplice tag è che plural e capfirst non sono né
variabili né stringhe, sono "parole chiave". Ovviamente potremmo decidere di passarli come
stringhe 'plural' e 'capfirst' , ma potrebbe entrare in conflitto con i campi con questi nomi. {%
verbose_name obj 'plural' %} significa "nome dettagliato plurale di obj " o "nome dettagliato di
obj.plural "?

Per prima cosa creiamo la funzione di compilazione:

@register.tag(name='verbose_name')
def do_verbose_name(parser, token):
"""
- parser: the Parser object. We will use it to parse tokens into
nodes such as variables, strings, ...
- token: the Token object. We will use it to iterate each token
of the template tag.
"""
# Split tokens within spaces (except spaces inside quotes)
tokens = token.split_contents()
tag_name = tokens[0]
try:
# each token is a string so we need to parse it to get the actual
# variable instead of the variable name as a string.
model = parser.compile_filter(tokens[1])
except IndexError:
raise TemplateSyntaxError(
"'{}' tag requires at least 1 argument.".format(tag_name))

field_name = None
flags = {
'plural': False,
'capfirst': False,
}

bits = tokens[2:]
for bit in bits:
if bit in flags.keys():
# here we don't need `parser.compile_filter` because we expect
# 'plural' and 'capfirst' flags to be actual strings.
if flags[bit]:
raise TemplateSyntaxError(
"'{}' tag only accept one occurrence of '{}' flag".format(
tag_name, bit)
)
flags[bit] = True
continue
if field_name:

https://riptutorial.com/it/home 181
raise TemplateSyntaxError((
"'{}' tag only accept one field name at most. {} is the second "
"field name encountered."
).format(tag_name, bit)
field_name = parser.compile_filter(bit)

# VerboseNameNode is our renderer which code is given right below


return VerboseNameNode(model, field_name, **flags)

E ora il renderer:

class VerboseNameNode(Node):

def __init__(self, model, field_name=None, **flags):


self.model = model
self.field_name = field_name
self.plural = flags.get('plural', False)
self.capfirst = flags.get('capfirst', False)

def get_field_verbose_name(self):
if self.plural:
raise ValueError("Plural is not supported for fields verbose name.")
return self.model._meta.get_field(self.field_name).verbose_name

def get_model_verbose_name(self):
if self.plural:
return self.model._meta.verbose_name_plural
else:
return self.model._meta.verbose_name

def render(self, context):


"""This is the main function, it will be called to render the tag.
As you can see it takes context, but we don't need it here.
For instance, an advanced version of this template tag could look for an
`object` or `object_list` in the context if `self.model` is not provided.
"""
if self.field_name:
verbose_name = self.get_field_verbose_name()
else:
verbose_name = self.get_model_verbose_name()
if self.capfirst:
verbose_name = verbose_name.capitalize()
return verbose_name

Leggi Tag e filtri modello online: https://riptutorial.com/it/django/topic/1305/tag-e-filtri-modello

https://riptutorial.com/it/home 182
Capitolo 46: templating
Examples
variabili

È possibile accedere alle variabili fornite nel contesto della vista utilizzando la notazione doppia
coppia:

Nel tuo views.py :

class UserView(TemplateView):
""" Supply the request user object to the template """

template_name = "user.html"

def get_context_data(self, **kwargs):


context = super(UserView, self).get_context_data(**kwargs)
context.update(user=self.request.user)
return context

In user.html :

<h1>{{ user.username }}</h1>

<div class="email">{{ user.email }}</div>

La notazione dot avrà accesso a:

• le proprietà dell'oggetto, ad es. user.username sarà {{ user.username }}


• ricerche nel dizionario, ad esempio request.GET["search"] sarà {{ request.GET.search }}
• metodi senza argomenti, ad esempio users.count() sarà {{ user.count }}

Le variabili del modello non possono accedere ai metodi che accettano argomenti.

Le variabili possono anche essere testate e ripetute:

{% if user.is_authenticated %}
{% for item in menu %}
<li><a href="{{ item.url }}">{{ item.name }}</a></li>
{% endfor %}
{% else %}
<li><a href="{% url 'login' %}">Login</a>
{% endif %}

Si accede agli URL utilizzando il formato {% url 'name' %} , dove i nomi corrispondono ai nomi nel
tuo urls.py

{% url 'login' %} - Probabilmente verrà visualizzato come /accounts/login/


{% url 'user_profile' user.id %} - Gli argomenti per gli URL sono forniti in ordine

https://riptutorial.com/it/home 183
{% url next %} : gli URL possono essere variabili

Templating in Views basate su classi

Puoi passare i dati a un modello in una variabile personalizzata.

Nel tuo views.py :

from django.views.generic import TemplateView


from MyProject.myapp.models import Item

class ItemView(TemplateView):
template_name = "item.html"

def items(self):
""" Get all Items """
return Item.objects.all()

def certain_items(self):
""" Get certain Items """
return Item.objects.filter(model_field="certain")

def categories(self):
""" Get categories related to this Item """
return Item.objects.get(slug=self.kwargs['slug']).categories.all()

Una semplice lista nel tuo item.html :

{% for item in view.items %}


<ul>
<li>{{ item }}</li>
</ul>
{% endfor %}

È anche possibile recuperare proprietà aggiuntive dei dati.

Assumendo che il modello di Item ha un name di campo:

{% for item in view.certain_items %}


<ul>
<li>{{ item.name }}</li>
</ul>
{% endfor %}

Templating in viste basate sulle funzioni

È possibile utilizzare un modello in una vista basata sulla funzione come segue:

from django.shortcuts import render

def view(request):
return render(request, "template.html")

https://riptutorial.com/it/home 184
Se si desidera utilizzare le variabili del modello, è possibile farlo come segue:

from django.shortcuts import render

def view(request):
context = {"var1": True, "var2": "foo"}
return render(request, "template.html", context=context)

Quindi, in template.html , puoi fare riferimento alle tue variabili in questo modo:

<html>
{% if var1 %}
<h1>{{ var2 }}</h1>
{% endif %}
</html>

Filtri modello

Il sistema di template Django ha tag e filtri integrati, che sono funzioni all'interno del template per
rendere il contenuto in un modo specifico. È possibile specificare più filtri con pipe e i filtri possono
avere argomenti, proprio come nella sintassi delle variabili.

{{ "MAINROAD 3222"|lower }} # mainroad 3222


{{ 10|add:15}} # 25
{{ "super"|add:"glue" }} # superglue
{{ "A7"|add:"00" }} # A700
{{ myDate | date:"D d M Y"}} # Wed 20 Jul 2016

Un elenco di filtri integrati disponibili può essere trovato su


https://docs.djangoproject.com/en/dev/ref/templates/builtins/#ref-templates-builtins-filters .

Creazione di filtri personalizzati

Per aggiungere i tuoi filtri modello, crea una cartella denominata templatetags all'interno della
cartella dell'app. Quindi aggiungi un __init__.py e il file il tuo file che conterrà i filtri:

#/myapp/templatetags/filters.py
from django import template

register = template.Library()

@register.filter(name='tostring')
def to_string(value):
return str(value)

Per utilizzare effettivamente il filtro è necessario caricarlo nel modello:

#templates/mytemplate.html
{% load filters %}
{% if customer_id|tostring = customer %} Welcome back {% endif%}

Trucchi

https://riptutorial.com/it/home 185
Anche se all'inizio i filtri sembrano semplici, consente di fare alcune cose interessanti:

{% for x in ""|ljust:"20" %}Hello World!{% endfor %} # Hello World!Hello World!Hel...


{{ user.name.split|join:"_" }} ## replaces whitespace with '_'

Vedi anche i tag dei modelli per maggiori informazioni.

Impedisci che i metodi sensibili vengano richiamati nei modelli

Quando un oggetto viene esposto al contesto del modello, sono disponibili i suoi metodi senza
argomenti. Questo è utile quando queste funzioni sono "getter". Ma può essere pericoloso se
questi metodi alterano alcuni dati o hanno alcuni effetti collaterali. Anche se probabilmente ti fidi
dello scrittore di modelli, potrebbe non essere a conoscenza degli effetti collaterali di una funzione
o pensare di chiamare l'attributo sbagliato per errore.

Dato il seguente modello:

class Foobar(models.Model):
points_credit = models.IntegerField()

def credit_points(self, nb_points=1):


"""Credit points and return the new points credit value."""
self.points_credit = F('points_credit') + nb_points
self.save(update_fields=['points_credit'])
return self.points_credit

Se scrivi questo, per errore, in un modello:

You have {{ foobar.credit_points }} points!

Ciò incrementerà il numero di punti ogni volta che viene chiamato il modello. E potresti anche non
accorgertene.

Per evitare ciò, è necessario impostare l'attributo alters_data su True per i metodi con effetti
collaterali. Ciò renderà impossibile chiamarli da un modello.

def credit_points(self, nb_points=1):


"""Credit points and return the new points credit value."""
self.points_credit = F('points_credit') + nb_points
self.save(update_fields=['points_credit'])
return self.points_credit
credit_points.alters_data = True

L'utilizzo di {% estende%}, {% include%} e {% blocchi%}

sommario
• {% extends%} : dichiara il modello fornito come argomento come padre del modello
corrente. Utilizzo: {% extends 'parent_template.html' %} .

https://riptutorial.com/it/home 186
• {% block%} {% endblock%} : questo è usato per definire sezioni nei tuoi template, così che
se un altro template estende questo, sarà in grado di sostituire qualunque codice html sia
stato scritto al suo interno. I blocchi sono identificati dal loro nome. Utilizzo: {% block content
%} <html_code> {% endblock %} .

• {% include%} : questo inserirà un modello all'interno di quello corrente. Tieni presente che il
modello incluso riceverà il contesto della richiesta e puoi dargli anche variabili
personalizzate. Utilizzo di base: {% include 'template_name.html' %} , utilizzo con variabili: {%
include 'template_name.html' with variable='value' variable2=8 %}

Guida
Supponiamo che tu stia costruendo il tuo codice lato front-end con layout comuni per tutto il codice
e non vuoi ripetere il codice per ogni modello. Django ti offre tag costruiti per farlo.
Supponiamo di avere un sito web di blog con 3 modelli che condividono lo stesso layout:

project_directory
..
templates
front-page.html
blogs.html
blog-detail.html

1) Definisci il file base.html ,

<html>
<head>
</head>

<body>
{% block content %}
{% endblock %}
</body>
</html>

2) Estendilo in blog.html come,

{% extends 'base.html' %}

{% block content %}
# write your blog related code here
{% endblock %}

# None of the code written here will be added to the template

Qui abbiamo esteso il layout di base in modo che il suo layout HTML sia ora disponibile nel
blog.html blog.html. Il concetto di { % block %} è l'ereditarietà del modello che ti consente di creare
un modello di base "scheletro" che contiene tutti gli elementi comuni del tuo sito e definisce i
blocchi che i modelli figlio possono sovrascrivere.

3) Supponiamo che tutti i tuoi 3 modelli abbiano anche lo stesso div HTML che definisce alcuni

https://riptutorial.com/it/home 187
post popolari. Invece di scrivere 3 volte, crea un nuovo template posts.html .

blog.html

{% extends 'base.html' %}

{% block content %}
# write your blog related code here
{% include 'posts.html' %} # includes posts.html in blog.html file without passing any
data
<!-- or -->
{% include 'posts.html' with posts=postdata %} # includes posts.html in blog.html file
with passing posts data which is context of view function returns.
{% endblock %}

Leggi templating online: https://riptutorial.com/it/django/topic/588/templating

https://riptutorial.com/it/home 188
Capitolo 47: Test unitario
Examples
Test: un esempio completo

Questo presuppone che tu abbia letto la documentazione sull'avvio di un nuovo progetto Django.
Supponiamo che l'app principale del progetto sia denominata td (abbreviazione di testing driven).
Per creare il tuo primo test, crea un file denominato test_view.py e copia incolla il seguente
contenuto in esso.

from django.test import Client, TestCase

class ViewTest(TestCase):

def test_hello(self):
c = Client()
resp = c.get('/hello/')
self.assertEqual(resp.status_code, 200)

Puoi eseguire questo test con

./manage.py test

e molto probabilmente fallirà! Verrà visualizzato un errore simile al seguente.

Traceback (most recent call last):


File "/home/me/workspace/td/tests_view.py", line 9, in test_hello
self.assertEqual(resp.status_code, 200)
AssertionError: 200 != 404

Perché succede? Perché non abbiamo definito una visione per questo! Facciamolo. Crea un file
chiamato views.py e inserisci il seguente codice

from django.http import HttpResponse


def hello(request):
return HttpResponse('hello')

Quindi mappalo al / ciao / modificando gli url py come segue:

from td import views

urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^hello/', views.hello),
....
]

Ora esegui nuovamente il test ./manage.py test nuovo e viola !!

https://riptutorial.com/it/home 189
Creating test database for alias 'default'...
.
----------------------------------------------------------------------
Ran 1 test in 0.004s

OK

Testare i modelli Django in modo efficace

Supponendo una lezione

from django.db import models

class Author(models.Model):
name = models.CharField(max_length=50)

def __str__(self):
return self.name

def get_absolute_url(self):
return reverse('view_author', args=[str(self.id)])

class Book(models.Model):
author = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)
private = models.BooleanField(default=false)
publish_date = models.DateField()

def get_absolute_url(self):
return reverse('view_book', args=[str(self.id)])

def __str__(self):
return self.name

Esempi di prova

from django.test import TestCase


from .models import Book, Author

class BaseModelTestCase(TestCase):

@classmethod
def setUpClass(cls):
super(BaseModelTestCase, cls).setUpClass()
cls.author = Author(name='hawking')
cls.author.save()
cls.first_book = Book(author=cls.author, name="short_history_of_time")
cls.first_book.save()
cls.second_book = Book(author=cls.author, name="long_history_of_time")
cls.second_book.save()

class AuthorModelTestCase(BaseModelTestCase):
def test_created_properly(self):
self.assertEqual(self.author.name, 'hawking')
self.assertEqual(True, self.first_book in self.author.book_set.all())

def test_absolute_url(self):

https://riptutorial.com/it/home 190
self.assertEqual(self.author.get_absolute_url(), reverse('view_author',
args=[str(self.author.id)]))

class BookModelTestCase(BaseModelTestCase):

def test_created_properly(self:
...
self.assertEqual(1, len(Book.objects.filter(name__startswith='long'))

def test_absolute_url(self):
...

Alcuni punti

• test created_properly vengono utilizzati per verificare le proprietà di stato dei


created_properly
modelli django. Aiutano a catturare le sitauzioni dove abbiamo cambiato i valori predefiniti,
file_upload_paths ecc.
• absolute_url potrebbe sembrare banale ma ho scoperto che mi ha aiutato a prevenire alcuni
bug durante la modifica dei percorsi di url
• Analogamente, scrivo casi di test per tutti i metodi implementati all'interno di un modello
(usando oggetti mock , ecc.)
• Definendo un BaseModelTestCase comune possiamo configurare le relazioni necessarie tra i
modelli per garantire un test corretto.

Infine, in caso di dubbio, scrivi un test. I cambiamenti del comportamento banale vengono catturati
prestando attenzione ai dettagli e lunghi pezzi di codice dimenticati non finiscono per causare
problemi inutili.

Testare il controllo degli accessi nelle viste Django

tl; dr : crea una classe base che definisce due oggetti utente (ad esempio user e another_user ).
Crea gli altri tuoi modelli e definisci tre istanze del Client .

• self.client : rappresenta l' user effettuato user accesso al browser


• self.another_client : Rappresentare another_user cliente 's
• self.unlogged_client : rappresenta la persona non self.unlogged_client

Ora accedi a tutti i tuoi URL pubblici e privati da questi tre oggetti client e imposta la risposta che ti
aspetti. Di seguito ho mostrato la strategia per un oggetto Book che può essere private (di
proprietà di pochi utenti privilegiati) o public (visibile a tutti).

from django.test import TestCase, RequestFactory, Client


from django.core.urlresolvers import reverse

class BaseViewTestCase(TestCase):

@classmethod
def setUpClass(cls):
super(BaseViewTestCase, cls).setUpClass()
cls.client = Client()
cls.another_client = Client()
cls.unlogged_client = Client()

https://riptutorial.com/it/home 191
cls.user = User.objects.create_user(
'dummy',password='dummy'
)
cls.user.save()
cls.another_user = User.objects.create_user(
'dummy2', password='dummy2'
)
cls.another_user.save()
cls.first_book = Book.objects.create(
name='first',
private = true
)
cls.first_book.readers.add(cls.user)
cls.first_book.save()
cls.public_book = Template.objects.create(
name='public',
private=False
)
cls.public_book.save()

def setUp(self):
self.client.login(username=self.user.username, password=self.user.username)
self.another_client.login(username=self.another_user.username,
password=self.another_user.username)

"""
Only cls.user owns the first_book and thus only he should be able to see it.
Others get 403(Forbidden) error
"""
class PrivateBookAccessTestCase(BaseViewTestCase):

def setUp(self):
super(PrivateBookAccessTestCase, self).setUp()
self.url = reverse('view_book',kwargs={'book_id':str(self.first_book.id)})

def test_user_sees_own_book(self):
response = self.client.get(self.url)
self.assertEqual(200, response.status_code)
self.assertEqual(self.first_book.name,response.context['book'].name)
self.assertTemplateUsed('myapp/book/view_template.html')

def test_user_cant_see_others_books(self):
response = self.another_client.get(self.url)
self.assertEqual(403, response.status_code)

def test_unlogged_user_cant_see_private_books(self):
response = self.unlogged_client.get(self.url)
self.assertEqual(403, response.status_code)

"""
Since book is public all three clients should be able to see the book
"""
class PublicBookAccessTestCase(BaseViewTestCase):

def setUp(self):
super(PublicBookAccessTestCase, self).setUp()
self.url = reverse('view_book',kwargs={'book_id':str(self.public_book.id)})

def test_user_sees_book(self):

https://riptutorial.com/it/home 192
response = self.client.get(self.url)
self.assertEqual(200, response.status_code)
self.assertEqual(self.public_book.name,response.context['book'].name)
self.assertTemplateUsed('myapp/book/view_template.html')

def test_another_user_sees_public_books(self):
response = self.another_client.get(self.url)
self.assertEqual(200, response.status_code)

def test_unlogged_user_sees_public_books(self):
response = self.unlogged_client.get(self.url)
self.assertEqual(200, response.status_code)

Il database e i test

Django utilizza impostazioni di database speciali durante i test in modo che i test possano
utilizzare normalmente il database, ma per impostazione predefinita vengono eseguiti su un
database vuoto. Le modifiche al database in un test non saranno viste da un altro. Ad esempio,
entrambi i seguenti test supereranno:

from django.test import TestCase


from myapp.models import Thing

class MyTest(TestCase):

def test_1(self):
self.assertEqual(Thing.objects.count(), 0)
Thing.objects.create()
self.assertEqual(Thing.objects.count(), 1)

def test_2(self):
self.assertEqual(Thing.objects.count(), 0)
Thing.objects.create(attr1="value")
self.assertEqual(Thing.objects.count(), 1)

infissi

Se si desidera disporre di oggetti di database utilizzati da più test, crearli nel metodo setUp del
caso di test. Inoltre, se hai definito fixtures nel tuo progetto django, possono essere inclusi in
questo modo:

class MyTest(TestCase):
fixtures = ["fixture1.json", "fixture2.json"]

Per impostazione predefinita, django è alla ricerca di fixture nella directory fixtures in ogni app.
Ulteriori directory possono essere impostate utilizzando l'impostazione FIXTURE_DIRS :

# myapp/settings.py
FIXTURE_DIRS = [
os.path.join(BASE_DIR, 'path', 'to', 'directory'),
]

Supponiamo che tu abbia creato un modello come segue:

https://riptutorial.com/it/home 193
# models.py
from django.db import models

class Person(models.Model):
"""A person defined by his/her first- and lastname."""
firstname = models.CharField(max_length=255)
lastname = models.CharField(max_length=255)

Quindi i tuoi apparecchi .json potrebbero assomigliare a questo:

# fixture1.json
[
{ "model": "myapp.person",
"pk": 1,
"fields": {
"firstname": "Peter",
"lastname": "Griffin"
}
},
{ "model": "myapp.person",
"pk": 2,
"fields": {
"firstname": "Louis",
"lastname": "Griffin"
}
},
]

Riutilizzare il database di test

Per accelerare le esecuzioni dei test, è possibile indicare al comando di gestione di riutilizzare il
database di test (e impedire che venga creato prima e eliminato dopo ogni esecuzione di prova).
Questo può essere fatto usando il flag keepdb (o shorthand -k ) in questo modo:

# Reuse the test-database (since django version 1.8)


$ python manage.py test --keepdb

Limita il numero di test eseguiti

È possibile limitare i test eseguiti dal manage.py test specificando quali moduli devono essere
rilevati dal test runner:

# Run only tests for the app names "app1"


$ python manage.py test app1

# If you split the tests file into a module with several tests files for an app
$ python manage.py test app1.tests.test_models

# it's possible to dig down to individual test methods.


$ python manage.py test app1.tests.test_models.MyTestCase.test_something

Se vuoi eseguire una serie di test, puoi passare uno schema di nomi di file. Ad esempio, potresti
voler eseguire solo test che coinvolgono i tuoi modelli:

https://riptutorial.com/it/home 194
$ python manage.py test -p test_models*
Creating test database for alias 'default'...
.................................................
----------------------------------------------------------------------
Ran 115 tests in 3.869s

OK

Infine, è possibile interrompere la suite di test al primo errore, usando --failfast . Questo
argomento consente di ottenere rapidamente il potenziale errore riscontrato nella suite:

$ python manage.py test app1


...F..
----------------------------------------------------------------------
Ran 6 tests in 0.977s

FAILED (failures=1)

$ python manage.py test app1 --failfast


...F
======================================================================
[Traceback of the failing test]
----------------------------------------------------------------------
Ran 4 tests in 0.372s

FAILED (failures=1)

Leggi Test unitario online: https://riptutorial.com/it/django/topic/1232/test-unitario

https://riptutorial.com/it/home 195
Capitolo 48: Transazioni di database
Examples
Transazioni atomiche

Problema
Per impostazione predefinita, Django commette immediatamente modifiche al database. Quando
si verificano eccezioni durante una serie di commit, questo può lasciare il tuo database in uno
stato indesiderato:

def create_category(name, products):


category = Category.objects.create(name=name)
product_api.add_products_to_category(category, products)
activate_category(category)

Nel seguente scenario:

>>> create_category('clothing', ['shirt', 'trousers', 'tie'])


---------------------------------------------------------------------------
ValueError: Product 'trousers' already exists

Si verifica un'eccezione durante il tentativo di aggiungere il prodotto pantaloni alla categoria di


abbigliamento. A questo punto, la categoria stessa è già stata aggiunta e il prodotto della
maglietta è stato aggiunto.

La categoria incompleta e il prodotto contenente dovrebbero essere rimossi manualmente prima di


correggere il codice e richiamare il metodo create_category() ancora una volta, altrimenti si
creerebbe una categoria duplicata.

Soluzione
Il modulo django.db.transaction consente di combinare più modifiche al database in una
transazione atomica :

[a] una serie di operazioni di database tali che si verificano tutte o non si verifica nulla.

Applicato allo scenario sopra, questo può essere applicato come decoratore :

from django.db import transaction

@transaction.atomic
def create_category(name, products):

https://riptutorial.com/it/home 196
category = Category.objects.create(name=name)
product_api.add_products_to_category(category, products)
activate_category(category)

O utilizzando un gestore di contesto :

def create_category(name, products):


with transaction.atomic():
category = Category.objects.create(name=name)
product_api.add_products_to_category(category, products)
activate_category(category)

Ora, se si verifica un'eccezione in qualsiasi fase della transazione, non verrà eseguito il commit
delle modifiche al database.

Leggi Transazioni di database online: https://riptutorial.com/it/django/topic/5555/transazioni-di-


database

https://riptutorial.com/it/home 197
Capitolo 49: Uso di Redis con Django -
Backend di cache
Osservazioni
Utilizzando django-redis-cache o django-redis sono entrambe soluzioni efficaci per la
memorizzazione di tutti gli elementi memorizzati nella cache. Mentre è certamente possibile
impostare Redis direttamente come SESSION_ENGINE , una strategia efficace consiste nell'impostare
la cache (come sopra) e dichiarare la cache predefinita come SESSION_ENGINE . Mentre questo è
veramente l'argomento di un altro articolo di documentazione, la sua rilevanza porta all'inclusione.

Aggiungi semplicemente quanto segue a settings.py :

SESSION_ENGINE = "django.contrib.sessions.backends.cache"

Examples
Utilizzando django-redis-cache

Una potenziale implementazione di Redis come utility di caching del back-end è il pacchetto
django-redis-cache .

Questo esempio presuppone che tu abbia già un server Redis in funzione .

$ pip install django-redis-cache

Modifica il tuo settings.py per includere un oggetto CACHES (vedi la documentazione di Django sulla
cache ).

CACHES = {
'default': {
'BACKEND': 'redis_cache.RedisCache',
'LOCATION': 'localhost:6379',
'OPTIONS': {
'DB': 0,
}
}
}

Usando il django-redis

Una potenziale implementazione di Redis come utility di caching del back-end è il pacchetto
django-redis .

Questo esempio presuppone che tu abbia già un server Redis in funzione .

https://riptutorial.com/it/home 198
$ pip install django-redis

Modifica il tuo settings.py per includere un oggetto CACHES (vedi la documentazione di Django sulla
cache ).

CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/1',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
}
}
}

Leggi Uso di Redis con Django - Backend di cache online:


https://riptutorial.com/it/django/topic/4085/uso-di-redis-con-django---backend-di-cache

https://riptutorial.com/it/home 199
Capitolo 50: Viste basate sulla classe
Osservazioni
Quando si usa CBV, spesso abbiamo bisogno di sapere esattamente quali metodi possiamo
sovrascrivere per ogni classe generica. Questa pagina della documentazione di django elenca
tutte le classi generiche con tutti i loro metodi appiattiti e gli attributi di classe che possiamo usare.

Inoltre, il sito Web Classy Class Based View fornisce le stesse informazioni con una bella
interfaccia interattiva.

Examples
Viste basate sulla classe

Le visualizzazioni basate su classi ti consentono di concentrarti su ciò che rende le tue


visualizzazioni speciali.

Una pagina statica sulla pagina potrebbe non avere nulla di speciale, tranne il modello usato. Usa
un TemplateView ! Tutto quello che devi fare è impostare un nome per il modello. Lavoro fatto. Il
prossimo.

views.py
from django.views.generic import TemplateView

class AboutView(TemplateView):
template_name = "about.html"

urls.py
from django.conf.urls import url
from . import views

urlpatterns = [
url('^about/', views.AboutView.as_view(), name='about'),
]

Si noti come non usiamo direttamente AboutView . Questo perché ci si aspetta un callable e questo
è esattamente ciò che as_view() restituisce.

Dati contestuali

https://riptutorial.com/it/home 200
A volte, il tuo modello ha bisogno di un po 'più di informazioni. Ad esempio, vorremmo avere
l'utente nell'intestazione della pagina, con un link al suo profilo accanto al link di disconnessione.
In questi casi, utilizzare il metodo get_context_data .

views.py
class BookView(DetailView):
template_name = "book.html"

def get_context_data(self, **kwargs)


""" get_context_data let you fill the template context """
context = super(BookView, self).get_context_data(**kwargs)
# Get Related publishers
context['publishers'] = self.object.publishers.filter(is_active=True)
return context

È necessario chiamare il metodo get_context_data sulla super classe e restituirà l'istanza di


contesto predefinita. Qualsiasi elemento aggiunto a questo dizionario sarà disponibile per il
modello.

book.html
<h3>Active publishers</h3>
<ul>
{% for publisher in publishers %}
<li>{{ publisher.name }}</li>
{% endfor %}
</ul>

Elenco e dettagli

Le viste del modello vanno bene per la pagina statica e potresti usarle per tutto con
get_context_data ma sarebbe a malapena migliore dell'uso della funzione come viste.

Inserisci ListView e DetailView

app / models.py
from django.db import models

class Pokemon(models.Model):
name = models.CharField(max_length=24)
species = models.CharField(max_length=48)
slug = models.CharField(max_length=48)

https://riptutorial.com/it/home 201
app / views.py
from django.views.generic import ListView, DetailView
from .models import Pokemon

class PokedexView(ListView):
""" Provide a list of Pokemon objects """
model = Pokemon
paginate_by = 25

class PokemonView(DetailView):
model = Pokemon

Questo è tutto ciò che serve per generare una vista che elenchi tutti gli oggetti di un modello e le
viste di un oggetto singolare. L'elenco è persino impaginato. Puoi fornire template_name se vuoi
qualcosa di specifico. Per impostazione predefinita, viene generato dal nome del modello.

app / templates / app / pokemon_list.html


<!DOCTYPE html>
<title>Pokedex</title>
<ul>{% for pokemon in pokemon_list %}
<li><a href="{% url "app:pokemon" pokemon.pk %}">{{ pokemon.name }}</a>
&ndash; {{ pokemon.species }}
</ul>

Il contesto è popolato con l'elenco di oggetti sotto il nome due, object_list e una seconda build
dal nome del modello, qui pokemon_list . Se hai impaginato la lista, devi occuparti anche del link
precedente e successivo. L'oggetto Paginator può essere d'aiuto, è disponibile anche nei dati di
contesto.

app / templates / app / pokemon_detail.html


<!DOCTYPE html>
<title>Pokemon {{ pokemon.name }}</title>
<h1>{{ pokemon.name }}</h1>
<h2>{{ pokemon.species }} </h2>

Come in precedenza, il contesto viene popolato con l'oggetto del modello sotto l' object nome e il
pokemon , il secondo derivato dal nome del modello.

app / urls.py
from django.conf.urls import url

https://riptutorial.com/it/home 202
from . import views

app_name = 'app'
urlpatterns = [
url(r'^pokemon/$', views.PokedexView.as_view(), name='pokedex'),
url(r'^pokemon/(?P<pk>\d+)/$', views.PokemonView.as_view(), name='pokemon'),
]

In questo snippet, l'url per la vista dettagliata viene creato utilizzando la chiave primaria. È anche
possibile usare una lumaca come argomento. Questo dà un URL più bello che è più facile da
ricordare. Tuttavia richiede la presenza di un campo chiamato slug nel tuo modello.

url(r'^pokemon/(?P<slug>[A-Za-z0-9_-]+)/$', views.PokemonView.as_view(), name='pokemon'),

Se un campo chiamato slug non è presente, è possibile utilizzare la slug_field impostazione


DetailView per puntare a un campo diverso.

Per l'impaginazione, utilizza una pagina per ottenere parametri o inserire una pagina direttamente
nell'URL.

Creazione di forme e oggetti

Scrivere una vista per creare oggetti può essere piuttosto noioso. Devi visualizzare un modulo,
devi convalidarlo, devi salvare l'oggetto o restituire il modulo con un errore. A meno che non si usi
una delle viste di modifica generiche .

app / views.py
from django.core.urlresolvers import reverse_lazy
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from .models import Pokemon

class PokemonCreate(CreateView):
model = Pokemon
fields = ['name', 'species']

class PokemonUpdate(UpdateView):
model = Pokemon
fields = ['name', 'species']

class PokemonDelete(DeleteView):
model = Pokemon
success_url = reverse_lazy('pokedex')

CreateView e UpdateView hanno due attributi, model e fields obbligatori. Per impostazione
predefinita, entrambi utilizzano un nome di modello basato sul nome del modello con suffisso
"_form". Puoi modificare solo il suffisso con l'attributo template_name_suffix. DeleteView mostra
un messaggio di conferma prima di eliminare l'oggetto.

https://riptutorial.com/it/home 203
Sia UpdateView che DeleteView devono recuperare l'oggetto. Usano lo stesso metodo di DetailView ,
estraendo la variabile dall'URL e facendo corrispondere i campi dell'oggetto.

app / templates / app / pokemon_form.html


(estratto)
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save" />
</form>

form contiene il modulo con tutti i campi necessari. Qui, verrà visualizzato con un paragrafo per
ogni campo a causa di as_p .

app / templates / app /


pokemon_confirm_delete.html (estratto)
<form action="" method="post">
{% csrf_token %}
<p>Are you sure you want to delete "{{ object }}"?</p>
<input type="submit" value="Confirm" />
</form>

Il tag csrf_token è richiesto a causa della protezione di django contro la falsificazione delle
richieste. L'azione attributo è lasciata vuota poiché l'url che visualizza il modulo è uguale a quello
che gestisce la cancellazione / salvataggio.

Rimangono due problemi con il modello, se si utilizza lo stesso esempio con l'elenco e l'esempio
di dettaglio. In primo luogo, creare e aggiornare si lamenterà di un URL di reindirizzamento
mancante. Questo può essere risolto aggiungendo un get_absolute_url al modello pokemon. Il
secondo problema è la conferma dell'eliminazione che non mostra informazioni significative. Per
risolvere questo problema, la soluzione più semplice è aggiungere una rappresentazione di
stringa.

app / models.py
from django.db import models
from django.urls import reverse
from django.utils.encoding import python_2_unicode_compatible

@python_2_unicode_compatible
class Pokemon(models.Model):

https://riptutorial.com/it/home 204
name = models.CharField(max_length=24)
species = models.CharField(max_length=48)

def get_absolute_url(self):
return reverse('app:pokemon', kwargs={'pk':self.pk})

def __str__(self):
return self.name

Il decoratore di classe si assicurerà che tutto funzioni correttamente sotto python 2.

Esempio minimo

views.py :

from django.http import HttpResponse


from django.views.generic import View

class MyView(View):
def get(self, request):
# <view logic>
return HttpResponse('result')

urls.py :

from django.conf.urls import url


from myapp.views import MyView

urlpatterns = [
url(r'^about/$', MyView.as_view()),
]

Ulteriori informazioni sulla documentazione di Django »

Viste basate sulla classe Django: esempio di CreateView

Con le viste generiche basate sulla classe, è molto semplice e facile creare le viste CRUD dai
nostri modelli. Spesso, l'amministratore di Django integrato non è abbastanza o non è preferito e
abbiamo bisogno di lanciare le nostre visualizzazioni CRUD. I CBV possono essere molto utili in
questi casi.

La classe CreateView bisogno di 3 cose: un modello, i campi da usare e l'url di successo.

Esempio:

from django.views.generic import CreateView


from .models import Campaign

class CampaignCreateView(CreateView):
model = Campaign
fields = ('title', 'description')

success_url = "/campaigns/list"

https://riptutorial.com/it/home 205
Una volta che il successo della creazione, l'utente viene reindirizzato a success_url . Possiamo
anche definire un metodo get_success_url e utilizzare reverse o reverse_lazy per ottenere l'URL di
successo.

Ora, dobbiamo creare un modello per questa vista. Il modello deve essere denominato nel formato
<app name>/<model name>_form.html . Il nome del modello deve essere in maiuscolo. Ad esempio, se
il mio nome dell'app è dashboard , per la vista create sopra devo creare un modello denominato
dashboard/campaign_form.html .

Nel modello, una variabile form contiene il modulo. Ecco un codice di esempio per il modello:

<form action="" method="post">


{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save" />
</form>

Ora è il momento di aggiungere la vista ai nostri modelli di URL.

url('^campaign/new/$', CampaignCreateView.as_view(), name='campaign_new'),

Se visitiamo l'URL, dovremmo vedere un modulo con i campi che abbiamo scelto. Quando
inviamo, cercherà di creare una nuova istanza del modello con i dati e salvarla. In caso di
successo, l'utente verrà reindirizzato all'URL di successo. In caso di errori, il modulo verrà
visualizzato di nuovo con i messaggi di errore.

Una vista, più moduli

Ecco un rapido esempio di utilizzo di più moduli in una vista Django.

from django.contrib import messages


from django.views.generic import TemplateView

from .forms import AddPostForm, AddCommentForm


from .models import Comment

class AddCommentView(TemplateView):

post_form_class = AddPostForm
comment_form_class = AddCommentForm
template_name = 'blog/post.html'

def post(self, request):


post_data = request.POST or None
post_form = self.post_form_class(post_data, prefix='post')
comment_form = self.comment_form_class(post_data, prefix='comment')

context = self.get_context_data(post_form=post_form,
comment_form=comment_form)

if post_form.is_valid():

https://riptutorial.com/it/home 206
self.form_save(post_form)
if comment_form.is_valid():
self.form_save(comment_form)

return self.render_to_response(context)

def form_save(self, form):


obj = form.save()
messages.success(self.request, "{} saved successfully".format(obj))
return obj

def get(self, request, *args, **kwargs):


return self.post(request, *args, **kwargs)

Leggi Viste basate sulla classe online: https://riptutorial.com/it/django/topic/1220/viste-basate-


sulla-classe

https://riptutorial.com/it/home 207
Capitolo 51: Visualizzazioni
introduzione
Una funzione di visualizzazione, o vista in breve, è semplicemente una funzione Python che
accetta una richiesta Web e restituisce una risposta Web. -Django Documentazione-

Examples
[Introduzione] Vista semplice (Hello World Equivalent)

Creiamo una vista molto semplice per rispondere a un modello "Hello World" in formato html.

1. Per farlo vai su my_project/my_app/views.py (Qui stiamo ospitando le nostre funzioni di


visualizzazione) e aggiungi la seguente vista:

from django.http import HttpResponse

def hello_world(request):
html = "<html><title>Hello World!</title><body>Hello World!</body></html>"
return HttpResponse(html)

2. Per chiamare questa vista, dobbiamo configurare un pattern url in my_project/my_app/urls.py


:

from django.conf.urls import url

from . import views

urlpatterns = [
url(r'^hello_world/$', views.hello_world, name='hello_world'),
]

3. Avviare il server: python manage.py runserver

Ora se http://localhost:8000/hello_world/ , il nostro modello (la stringa html) verrà


visualizzato nel nostro browser.

Leggi Visualizzazioni online: https://riptutorial.com/it/django/topic/7490/visualizzazioni

https://riptutorial.com/it/home 208
Capitolo 52: Visualizzazioni generiche
introduzione
Le viste generiche sono viste che eseguono una determinata azione predefinita, come la
creazione, la modifica o l'eliminazione di oggetti o semplicemente la visualizzazione di un modello.

Le viste generiche devono essere distinte dalle viste funzionali, che sono sempre scritte a mano
per eseguire le attività richieste. In breve, si può dire che le viste generiche devono essere
configurate, mentre le viste funzionali devono essere programmate.

Le viste generiche possono risparmiare molto tempo, specialmente quando si devono eseguire
molte attività standardizzate.

Osservazioni
Questi esempi mostrano che le viste generiche generalmente semplificano le attività
standardizzate. Invece di programmare tutto da capo, puoi configurare ciò che altre persone
hanno già programmato per te. Questo ha senso in molte situazioni, in quanto consente di
concentrarsi maggiormente sulla progettazione dei progetti piuttosto che sui processi in
background.

Quindi, dovresti sempre usarli? No. Hanno senso solo se i tuoi compiti sono abbastanza
standardizzati (caricamento, modifica, eliminazione di oggetti) e più ripetitivi sono i tuoi compiti.
L'utilizzo di una vista generica specifica solo una volta e quindi l'annullamento di tutti i suoi metodi
per eseguire attività molto specifiche potrebbe non avere senso. Potresti star meglio con una vista
funzionale qui.

Tuttavia, se disponi di molte viste che richiedono questa funzionalità o se le tue attività
corrispondono esattamente alle attività definite di una vista generica specifica, le visualizzazioni
generiche sono esattamente ciò di cui hai bisogno per semplificarti la vita.

Examples
Esempio minimo: viste funzionali e generiche

Esempio per una vista funzionale per creare un oggetto. Escludendo i commenti e le righe vuote,
abbiamo bisogno di 15 righe di codice:

# imports
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect

from .models import SampleObject


from .forms import SampleObjectForm

https://riptutorial.com/it/home 209
# view functioon
def create_object(request):

# when request method is 'GET', show the template


if request.method == GET:
# perform actions, such as loading a model form
form = SampleObjectForm()
return render_to_response('template.html', locals())

# if request method is 'POST', create the object and redirect


if request.method == POST:
form = SampleObjectForm(request.POST)

# save object and redirect to success page if form is valid


if form.is_valid:
form.save()
return HttpResponseRedirect('url_to_redirect_to')

# load template with form and show errors


else:
return render_to_response('template.html', locals())

Esempio di una 'vista generica basata su classi' per eseguire la stessa operazione. Abbiamo solo
bisogno di 7 linee di codice per ottenere lo stesso compito:

from django.views.generic import CreateView

from .models import SampleObject


from .forms import SampleObjectForm

class CreateObject(CreateView):
model = SampleObject
form_class = SampleObjectForm
success_url = 'url_to_redirect_to'

Personalizzazione delle viste generiche

L'esempio precedente funziona solo se le tue attività sono interamente attività standard. Ad
esempio, non aggiungi qui un contesto extra.

Facciamo un esempio più realistico. Supponiamo di voler aggiungere un titolo di pagina al


modello. Nella vista funzionale, funzionerebbe in questo modo - con una sola riga aggiuntiva:

def create_object(request):
page_title = 'My Page Title'

# ...

return render_to_response('template.html', locals())

Questo è più difficile (o: controtestivo) da ottenere con visualizzazioni generiche. Poiché sono
basati su classi, devi eseguire l'override di uno o più metodi della classe per ottenere il risultato
desiderato. Nel nostro esempio, abbiamo bisogno di sovrascrivere il metodo get_context_data
della classe in questo modo:

https://riptutorial.com/it/home 210
class CreateObject(CreateView):
model = SampleObject
form_class = SampleObjectForm
success_url = 'url_to_redirect_to'

def get_context_data(self, **kwargs):

# Call class's get_context_data method to retrieve context


context = super().get_context_data(**kwargs)

context['page_title'] = 'My page title'


return context

Qui, abbiamo bisogno di quattro righe aggiuntive da codificare invece di una sola, almeno per la
prima variabile di contesto che vogliamo aggiungere.

Visualizzazioni generiche con Mixins

Il vero potere delle viste generiche si sviluppa quando le combini con Mixins. Un mixin è solo
un'altra classe definita da te i cui metodi possono essere ereditati dalla tua classe di
visualizzazione.

Supponi di volere che ogni vista mostri la variabile aggiuntiva 'page_title' nel modello. Invece di
sovrascrivere il metodo get_context_data ogni volta che definisci la vista, crei un mixin con questo
metodo e consenti alle tue opinioni di ereditare da questo mix. Sembra più complicato di quanto
non sia in realtà:

# Your Mixin
class CustomMixin(object):

def get_context_data(self, **kwargs):

# Call class's get_context_data method to retrieve context


context = super().get_context_data(**kwargs)

context['page_title'] = 'My page title'


return context

# Your view function now inherits from the Mixin


class CreateObject(CustomMixin, CreateView):
model = SampleObject
form_class = SampleObjectForm
success_url = 'url_to_redirect_to'

# As all other view functions which need these methods


class EditObject(CustomMixin, EditView):
model = SampleObject
# ...

La bellezza di questo è che il tuo codice diventa molto più strutturato di quanto non avvenga per le
visualizzazioni funzionali. La tua intera logica dietro compiti specifici si trova in un posto e solo in
un posto. Inoltre, risparmierai enormi quantità di tempo, specialmente quando hai molte viste che
svolgono sempre le stesse attività, tranne che con oggetti diversi

https://riptutorial.com/it/home 211
Leggi Visualizzazioni generiche online: https://riptutorial.com/it/django/topic/9452/visualizzazioni-
generiche

https://riptutorial.com/it/home 212
Capitolo 53: Widget del modulo
Examples
Semplice widget di inserimento del testo

L'esempio più semplice di widget è l'inserimento di testo personalizzato. Ad esempio, per creare
un <input type="tel"> , devi sottoclasse TextInput e imposta input_type su 'tel' .

from django.forms.widgets import TextInput

class PhoneInput(TextInput):
input_type = 'tel'

Widget composito

Puoi creare widget composti da più widget usando MultiWidget .

from datetime import date

from django.forms.widgets import MultiWidget, Select


from django.utils.dates import MONTHS

class SelectMonthDateWidget(MultiWidget):
"""This widget allows the user to fill in a month and a year.

This represents the first day of this month or, if `last_day=True`, the
last day of this month.
"""

default_nb_years = 10

def __init__(self, attrs=None, years=None, months=None, last_day=False):


self.last_day = last_day

if not years:
this_year = date.today().year
years = range(this_year, this_year + self.default_nb_years)
if not months:
months = MONTHS

# Here we will use two `Select` widgets, one for months and one for years
widgets = (Select(attrs=attrs, choices=months.items()),
Select(attrs=attrs, choices=((y, y) for y in years)))
super().__init__(widgets, attrs)

def format_output(self, rendered_widgets):


"""Concatenates rendered sub-widgets as HTML"""
return (
'<div class="row">'
'<div class="col-xs-6">{}</div>'
'<div class="col-xs-6">{}</div>'
'</div>'
).format(*rendered_widgets)

https://riptutorial.com/it/home 213
def decompress(self, value):
"""Split the widget value into subwidgets values.
We expect value to be a valid date formated as `%Y-%m-%d`.
We extract month and year parts from this string.
"""
if value:
value = date(*map(int, value.split('-')))
return [value.month, value.year]
return [None, None]

def value_from_datadict(self, data, files, name):


"""Get the value according to provided `data` (often from `request.POST`)
and `files` (often from `request.FILES`, not used here)
`name` is the name of the form field.

As this is a composite widget, we will grab multiple keys from `data`.


Namely: `field_name_0` (the month) and `field_name_1` (the year).
"""
datalist = [
widget.value_from_datadict(data, files, '{}_{}'.format(name, i))
for i, widget in enumerate(self.widgets)]
try:
# Try to convert it as the first day of a month.
d = date(day=1, month=int(datelist[0]), year=int(datelist[1]))
if self.last_day:
# Transform it to the last day of the month if needed
if d.month == 12:
d = d.replace(day=31)
else:
d = d.replace(month=d.month+1) - timedelta(days=1)
except (ValueError, TypeError):
# If we failed to recognize a valid date
return ''
else:
# Convert it back to a string with format `%Y-%m-%d`
return str(d)

Leggi Widget del modulo online: https://riptutorial.com/it/django/topic/1230/widget-del-modulo

https://riptutorial.com/it/home 214
Titoli di coda
S.
Capitoli Contributors
No

A. Raza, Abhishek Jain, Aidas Bendoraitis, Alexander Tyapkov,


Ankur Gupta, Anthony Pham, Antoine Pinsard, arifin4web,
Community, e4c5, elbear, ericdwang, ettanany, Franck
Dernoncourt, greatwolf, ilse2005, Ivan Semochkin, J F, Jared
Hooper, John, John Moutafis, JRodDynamite, Kid Binary, knbk,
1 Iniziare con Django
Louis, Luis Alberto Santana, lxer, maciek, McAbra, MiniGunnR,
mnoronha, Nathan Osman, naveen.panwar, nhydock, Nikita
Davidenko, noɥʇʎԀʎzɐɹƆ, Rahul Gupta, rajarshig, Ron, ruddra,
sarvajeetsuman, shacker, ssice, Stryker, techydesigner, The
Brewmaster, Thereissoupinmyfly, Tom, WesleyJohnson, Zags

Aggregazioni di
2 Ian Clark, John Moutafis, ravigadila
modelli

Antoine Pinsard, coffee-grinder, George H., Ivan Semochkin,


3 Amministrazione
noɥʇʎԀʎzɐɹƆ, ssice

ArrayField - un campo
4 Antoine Pinsard, e4c5, noɥʇʎԀʎzɐɹƆ
specifico PostgreSQL

Associazione di
stringhe alle stringhe
5 con HStoreField: un noɥʇʎԀʎzɐɹƆ
campo specifico
PostgreSQL

Attività asincrone
6 iankit, Mevin Babu
(sedano)

Backend di
7 knbk, Rahul Gupta
autenticazione

Antoine Pinsard, aquasan, Brian Artschwager, HorsePunchKid,


8 Comandi di gestione Ivan Semochkin, John Moutafis, knbk, lxer, MarZab, Nikolay
Fominyh, pbaranay, ptim, Rana Ahmed, techydesigner, Zags

Come resettare le
9 Cristus Cleetus
migrazioni di django

Come usare Django


10 Atul Mishra, noɥʇʎԀʎzɐɹƆ, OliPro007, RamenChef
con Cookiecutter?

https://riptutorial.com/it/home 215
Configurazione del Ahmad Anwar, Antoine Pinsard, Evans Murithi, Kid Binary,
11
database knbk, lxer, Majid, Peter Mortensen

12 CRUD in Django aisflat439, George H.

13 Debug Antoine Pinsard, Ashutosh, e4c5, Kid Binary, knbk, Sayse, Udi

Antoine Pinsard, Arpit Solanki, CodeFanatic23, I Am Batman,


Ivan Semochkin, knbk, lxer, Maxime S., MaxLunar, Meska, no
14 Distribuzione
ɥʇʎԀʎzɐɹƆ, rajarshig, Rishabh Agrahari, Roald Nefs, Rohini
Choudhary, sebb

Django dalla riga di


15 e4c5, OliPro007
comando.

Aidas Bendoraitis, aisflat439, Carlos Rojas, Ivan Semochkin,


16 Django e reti sociali
Rexford, Simplans

Django Rest
17 The Brewmaster
Framework

18 django-filtro 4444, Ahmed Atalla

Esecuzione di Celery
19 RéÑjïth, sebb
con Supervisor

Estensione o Antoine Pinsard, Jon Clements, mnoronha, Raito, Rexford,


20 sostituzione del rigdonmr, Rishabh Agrahari, Roald Nefs, techydesigner,
modello utente The_Cthulhu_Kid

Antoine Pinsard, John Moutafis, Linville, Omar Shehata,


21 F () espressioni
RamenChef, Roald Nefs

22 formsets naveen.panwar

23 Fusi orari William Reed

Gestori e Queryys
24 abidibo, knbk, sudshekhar, Trivial
personalizzati

allo, Antoine Pinsard, Brian Artschwager, fredley, J F, knbk,


Louis, Louis Barranqueiro, lxer, Maxime Lorant, NBajanca, Nils
25 impostazioni
Werner, ProfSmiles, RamenChef, Sanyam Khurana, Sayse,
Selcuk, SpiXel, ssice, sudshekhar, Tema, The Brewmaster

Integrazione continua
26 pnovotnak
con Jenkins

27 Internazionalizzazione Antoine Pinsard, dmvrtx

https://riptutorial.com/it/home 216
JSONField - un
Antoine Pinsard, Daniil Ryzhkov, Matthew Schinckel, noɥʇʎԀ
28 campo specifico
ʎzɐɹƆ, Omar Shehata, techydesigner
PostgreSQL

Aidas Bendoraitis, Antoine Pinsard, Daniel Rucci, ettanany,


29 Le forme George H., knbk, NBajanca, nicorellius, RamenChef,
rumman0786, sudshekhar, trpt4him

Meta: linee guida per


30 Antoine Pinsard
la documentazione

AlvaroAV, Antoine Pinsard, George H., knbk, lxer, nhydock,


31 middleware
Omar Shehata, Peter Mortensen, Trivial, William Reed

Antoine Pinsard, engineercoding, Joey Wilhelm, knbk,


32 migrazioni
MicroPyramid, ravigadila, Roald Nefs

Aidas Bendoraitis, Alireza Aghamohammadi, alonisser, Antoine


Pinsard, aquasan, Arpit Solanki, atomh33ls, coffee-grinder,
DataSwede, ettanany, Gahan, George H., gkr, Ivan Semochkin
, Jamie Cockburn, Joey Wilhelm, kcrk, knbk, Linville, lxer,
33 Modelli
maazza, Matt Seymour, MuYi, Navid777, nhydock, noɥʇʎԀ
ʎzɐɹƆ, pbaranay, PhoebeB, Rana Ahmed, Saksow, Sanyam
Khurana, scriptmonster, Selcuk, SpiXel, sudshekhar,
techydesigner, The_Cthulhu_Kid, Utsav T, waterproof, zurfyx

Antoine Pinsard, Brian Artschwager, Dan Russell, Daniil


34 Processori di contesto
Ryzhkov, fredley

RangeFields: un
gruppo di campi
35 Antoine Pinsard, noɥʇʎԀʎzɐɹƆ
specifici di
PostgreSQL

36 Registrazione Antwane, Brian Artschwager, RamenChef

37 Relazioni molti-a-molti Antoine Pinsard, e4c5, knbk, Kostronor

Riferimento del Burhan Khalid, Husain Basrawala, knbk, Matt Seymour, Rod
38
campo del modello Xavier, scriptmonster, techydesigner, The_Cthulhu_Kid

39 Router di database fredley, knbk

40 Routing URL knbk

Antoine Pinsard, e4c5, Hetdev, John Moutafis, Majid, nhydock,


41 segnali
Rexford

Antoine Pinsard, Brian Artschwager, Chalist, coffee-grinder,


42 set di query
DataSwede, e4c5, Evans Murithi, George H., John Moutafis,

https://riptutorial.com/it/home 217
Justin, knbk, Louis Barranqueiro, Maxime Lorant,
MicroPyramid, nima, ravigadila, Sanyam Khurana, The
Brewmaster

43 Sicurezza Antoine Pinsard, knbk

44 Struttura del progetto Antoine Pinsard, naveen.panwar, nicorellius

Antoine Pinsard, irakli khitarishvili, knbk, Medorator,


45 Tag e filtri modello
naveen.panwar, The_Cthulhu_Kid

Adam Starrh, Alasdair, Aniket, Antoine Pinsard, Brian H.,


46 templating coffee-grinder, doctorsherlock, fredley, George H., gkr, lxer,
Stephen Leppik, Zags

Adrian17, Antoine Pinsard, e4c5, Kim, Matthew Schinckel,


47 Test unitario
Maxime Lorant, Patrik Stenmark, SandroM, sudshekhar, Zags

Transazioni di
48 Ian Clark
database

Uso di Redis con


49 Django - Backend di Majid, The Brewmaster
cache

Antoine Pinsard, Antwane, coffee-grinder, e4c5, gkr, knbk,


Viste basate sulla
50 maciek, masnun, Maxime Lorant, nicorellius, pleasedontbelong
classe
, Pureferret

51 Visualizzazioni ettanany, HorsePunchKid, John Moutafis

Visualizzazioni
52 nikolas-berlin
generiche

53 Widget del modulo Antoine Pinsard, ettanany

https://riptutorial.com/it/home 218

Potrebbero piacerti anche