Scrivere la tua prima applicazione in Django, parte 7

Questo tutorial inizia dove si è interrotto Tutorial 6. Stiamo proseguendo con l’applicazione web per i questionari e ci concentreremo sul sito generato automaticamente per l’amministrazione di Django che abbiamo esplorato in prima battuta nel Tutorial 2.

Dove trovare aiuto:

Se hai difficoltà a completare questo tutorial, per favore vai alla sezione Getting Help delle FAQ.

Personalizzare il modulo di amministrazione

Registrando il modello Question con admin.site.register(Question), Django è stato in grado di costruire un form di default. Spesso, vorrai personalizzare il modo in cui il form di amministrazione appare e funziona. Lo farai dicendo a Django quali opzioni vuoi quando registrerai l’oggetto.

Vediamo come funziona riordinando i campi nel modulo di modifica. Sostituisci la riga admin.site.register(Question) con:

polls/admin.py
from django.contrib import admin

from .models import Question


class QuestionAdmin(admin.ModelAdmin):
    fields = ['pub_date', 'question_text']

admin.site.register(Question, QuestionAdmin)

Seguirai questo pattern – crea una classe del modello di amministrazione, poi passala come secondo argomento a admin.site.register() – ogni volta che vuoi cambiare le opzioni nel panello di amministrazione del modello.

Questa particolare modifica qui sopra fa sì che la «Data di pubblicazione» venga prima del campo «Domanda»:

I campi sono stati riordinati

Questo non è impressionante con solo due campi, ma per i moduli di amministrazione con dozzine di campi, la scelta di un ordine intuitivo è un dettaglio importante per l’usabilità.

E parlando di moduli con dozzine di campi, potresti voler dividere il modulo in gruppi di campi:

polls/admin.py
from django.contrib import admin

from .models import Question


class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,               {'fields': ['question_text']}),
        ('Date information', {'fields': ['pub_date']}),
    ]

admin.site.register(Question, QuestionAdmin)

Il primo elemento di ogni tupla in fieldsets è il titolo del fieldset. Ecco come il nostro form appare adesso:

I form ora hanno i fieldset

Personalizzazione della lista per la modifica dell’interfaccia di amministrazione

Ora che la pagina di amministrazione del modello Question sembra buona, facciamo qualche modifica alla pagina di «change list» – quella che mostra tutte le domande nel sistema.

Ecco come appare a questo punto:

Pagina della lista dei cambiamenti dei sondaggi

Di default, Django mostra la str() di ogni oggetto. Qualche volta però può essere più utile se potessimo mostrare campi individuali. Per fare questo, usa l’opzione di amministrazione list_display, che è una tupla di nomi di campi da mostrare, come colonne, sulla pagina della lista dei cambiamenti per l’oggetto:

polls/admin.py
class QuestionAdmin(admin.ModelAdmin):
    # ...
    list_display = ('question_text', 'pub_date')

Di buona norma, aggiungiamo il metodo was_published_recently() da Tutorial 2:

polls/admin.py
class QuestionAdmin(admin.ModelAdmin):
    # ...
    list_display = ('question_text', 'pub_date', 'was_published_recently')

Ora la pagina di elenco delle domande ha questo aspetto:

La pagina dei cambiamenti relativi ai sondaggi, aggiornata

Puoi fare click sull’intestazione delle colonne per ordinare quei valori – eccetto nel caso di was_published_recently perchè l’ordinamento dell’output di un metodo non è supportato. Nota anche che l’intestazione di colonna per was_published_recently è, di default, il nome del metodo (con gli underscore a rimpiazzare gli spazi), e che ogni linea contiene la rappresentazione in stringa dell’oggetto.

Puoi migliorarlo usando il decoratore display() su quel metodo (in polls/models.py), come segue:

polls/models.py
from django.contrib import admin

class Question(models.Model):
    # ...
    @admin.display(
        boolean=True,
        ordering='pub_date',
        description='Published recently?',
    )
    def was_published_recently(self):
        now = timezone.now()
        return now - datetime.timedelta(days=1) <= self.pub_date <= now

Per più informazioni sulle proprietà configurabili attraverso il decoratore, vedi list_display.

Modifica nuovamente il tuo file polls/admin.py e aggiungi un miglioramento alla pagina dell’elenco di modifiche Domanda: i filtri usando list_filter. Aggiungi la seguente riga in QuestionAdmin:

list_filter = ['pub_date']

Questo aggiunge una sidebar «Filtra» che permette all’utente di filtrare la lista per il campo pub_date:

La pagina dei cambiamenti relativi ai sondaggi, aggiornata

Il tipo di filtro visualizzato dipende dal tipo di campo su cui stai filtrando. Poiché pub_date è un DateTimeField, Django sa fornire le opzioni di filtro appropriate: «Qualsiasi data», «Oggi», «Ultimi 7 giorni», «Questo mese», «Quest’anno».

Sta venendo su bene. Aggiungiamo alcune funzionalità di ricerca:

search_fields = ['question_text']

Ciò aggiunge una casella di ricerca all’inizio dell’elenco delle modifiche. Quando qualcuno inserisce i termini di ricerca, Django cercherà nel campo question_text. Puoi utilizzare tutti i campi che desideri – anche se poiché utilizza una query LIKE dietro le quinte, limitare il numero di campi di ricerca a un numero ragionevole renderà più facile per il tuo database fare la ricerca.

Adesso è anche un buon momento per notare che le liste dei cambiamenti ti danno la paginazione gratis. Di default, mostra 100 elementi per pagina. Change list pagination, search boxes, filters, date-hierarchies, e column-header-ordering lavorano tutti assieme come pensi che dovrebbero.

Personalizza l’aspetto dell’amministrazione

Chiaramente, avere «Django administration» nella parte superiore di ogni pagina di amministrazione è ridicolo. È solo testo segnaposto.

Puoi comunque cambiarlo, usando il sistema di template di Django. L’admin di Django è costruita su Django stesso, e dunque le sue interfacce usano il sistema di template di Django.

Personalizzare i template del tuo progetto

Crea una directory templates nella directory del tuo progetto (quella che contiene manage.py). I modelli possono risedere ovunque sul tuo filesystem purché Django vi possa accedere. (Django viene eseguito come qualsiasi utente venga eseguito dal server.) Tuttavia, mantenere i modelli all’interno del progetto è una buona convenzione da seguire.

Apri il tuo file delle impostazioni (mysite/settings.py, ricorda) e aggiungi un’opzione DIRS nell’impostazione TEMPLATES:

mysite/settings.py
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [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',
            ],
        },
    },
]

DIRS è una lista di directory su disco da controllare quando si caricano i template di Django; è un percorso di ricerca.

Organizzazione dei template

Proprio come i file statici, potremmo avere tutti i nostri modelli insieme, in una grande directory di modelli, e funzionerebbe perfettamente. Tuttavia, i modelli che appartengono a una particolare applicazione dovrebbero essere collocati nella directory dei modelli dell’applicazione(es. polls/templates) piuttosto che in quelli del progetto (templates). Discuteremo più in dettaglio nel reusable apps tutorial perché lo facciamo.

Ora crea una directory chiamata admin all’interno di `templates e copia il modello admin/base_site.html dalla directory predefinita dei modelli di amministrazione di Django nel codice sorgente di Django stesso (django/contrib/admin/templates) in quella directory.

Dove sono i file sorgenti di Django?

Se hai difficoltà a trovare dove si trovano i file sorgente di Django sul tuo sistema, esegui il seguente comando:

$ python -c "import django; print(django.__path__)"
...\> py -c "import django; print(django.__path__)"

Quindi, modifica il file e sostituisci {{ site_header|default:_('Django administration') }} (comprese le parentesi graffe) con il nome del tuo sito come meglio credi. Dovresti finire con una sezione di codice tipo:

{% block branding %}
<h1 id="site-name"><a href="{% url 'admin:index' %}">Polls Administration</a></h1>
{% endblock %}

Usiamo questo approccio per insegnarti come sovrascrivere i modelli. In un progetto reale, probabilmente useresti l’attributo: django.contrib.admin.AdminSite.site_header per realizzare più facilmente questa particolare personalizzazione.

Questo file di template contiene molto testo come {% block branding %} e {{ title }}. I tag {% e {{ sono parte del linguaggio di template di Django. Quando Django mostra admin/base_site.html, questo linguaggio di template sarà valutato per produrre la pagina HTML finale, come abbiamo visto in Tutorial 3.

Nota che qualsiasi template predefinito del pannello di amministrazione di Django può essere sovrascritto. Per sovrascrivere un template, fai la stessa cosa che hai fatto con base_site.html – copialo dalla directory predefinita nella tua directory personalizzata e apporta le modifiche.

Personalizzare i template della tua applicazione

I lettori più attenti chiederanno: Ma se: l’impostazione: DIRS <TEMPLATES-DIRS> era vuota per impostazione predefinita, come ha fatto Django a trovare i modelli di amministrazione predefiniti? La risposta è che, poiché APP_DIRS è impostato su True, Django cerca automaticamente una sottodirectory templates/ all’interno di ogni pacchetto dell’applicazione, da usare come fallback (non dimenticare che django.contrib.admin è un’applicazione).

La nostra applicazione per i sondaggi non è molto complessa e non necessita di modelli di admin personalizzati. Ma se diventasse più sofisticato e richiedesse la modifica dei modelli di amministrazione standard di Django per alcune delle sue funzionalità, sarebbe più sensato modificare i modelli nell’applicazione, piuttosto che quelli nel progetto. In questo modo, potresti includere l’applicazione sondaggi in qualsiasi nuovo progetto e avere la certezza che troverà i modelli personalizzati di cui ha bisogno.

Vedi la documentazione sul caricamento dei template per ulteriori informazioni su come Django trova i suoi template.

Personalizza l’indice dell’amministrazione

In modo simile, potresti voler personalizzare l’aspetto della pagina dell’indice di amministrazione di Django.

Di default, mostra tutte le app in INSTALLED_APPS che sono state registrate con l’applicazione di admin, in ordine alfabetico. Potresti voler apportare modifiche significative al layout. Dopotutto, l’indice è probabilmente la pagina più importante dell’amministratore e dovrebbe essere facile da usare.

Il modello da personalizzare è admin/index.html. (Fai lo stesso di admin/base_site.html nella sezione precedente - copialo dalla directory predefinita alla directory del tuo modello personalizzato). Modifica il file e vedrai che utilizza una variabile di modello chiamata app_list. Quella variabile contiene tutte le app Django installate. Invece di usarlo, puoi codificare link a pagine di amministrazione specifiche degli oggetti nel modo che ritieni migliore.

Cos’altro?

Il tutorial per principianti termina qui. Nel frattempo, potresti voler controllare alcuni suggerimenti su dove andare da qui.

Se hai familiarità con la creazione di pacchetti Python e sei interessato a imparare come trasformare i sondaggi in una «app riutilizzabile», controlla Tutorial avanzato: come scrivere app riutilizzabili.

Back to Top