Ora siamo pronti per aggiungere il codice che mostra la nostra prima pagina completa: una home page per il sito Web di LocalLibrary. La home page mostrerà il numero di record che abbiamo per ogni tipo di modello e fornirà i link di navigazione della barra laterale alle nostre altre pagine. Lungo la strada acquisiremo esperienza pratica nella scrittura di mappe e viste URL di base, leggendo record dal database e utilizzando templates.

Prerequisiti: Leggere Django Introduction e Django Tutorial Part 4: Django admin site.
Obiettivi: Impara a creare semplici mappe url e viste (in cui nessun dato è codificato nell'URL), ottienere dati dai modelli e creare modelli.

Panoramica

Dopo aver definito i nostri modelli e creato alcuni record della libreria iniziale con cui lavorare, è tempo di scrivere il codice che presenta tali informazioni agli utenti. La prima cosa che dobbiamo fare è determinare quali informazioni vogliamo visualizzare nelle nostre pagine e definire gli URL da utilizzare per restituire tali risorse. Quindi creeremo un URL mapper, visualizzazioni e templates per visualizzare le pagine.

Il diagramma seguente descrive il flusso di dati principale e i componenti richiesti durante la gestione delle richieste e delle risposte HTTP. Siccome abbiamo già implementato il modello, i componenti principali che creeremo sono:

  • Mapper URL per inoltrare gli URL supportati (e qualsiasi informazione codificata negli URL) alle funzioni di visualizzazione appropriate.
  • Funzioni di visualizzazione per ottenere i dati richiesti dai modelli, creare pagine HTML che visualizzano i dati e restituire le pagine all'utente per visualizzarle nel browser. Modelli da utilizzare durante il rendering dei dati nelle viste.

Come vedrai nella prossima sezione, abbiamo 5 pagine da visualizzare, che sono troppe informazioni da documentare in un singolo articolo. Pertanto, questo articolo si concentrerà su come implementare la home page e tratteremo le altre pagine in un articolo successivo. Questo dovrebbe darti una buona comprensione end-to-end di come funzionano in pratica i mappatori, le viste e i modelli.

Definizione degli URL delle risorse

Siccome questa LocalLibrary è essenzialmente di sola lettura per gli utenti finali, abbiamo solo bisogno di fornire una pagina di destinazione per il sito (una home page) e pagine che visualizzano elenchi e viste di dettaglio per libri e autori.

Gli URL di cui avremo bisogno per le nostre pagine sono:

  • catalog/ — La home page.
  • catalog/books/ — Lista di libri.
  • catalog/authors/ — Lista di tutti gli autori.
  • catalog/book/<id> — La vista dettagliata per un libro particolare, con una chiave primaria del campo di <id> (impostazione predefinita). Ad esempio, l'URL per il terzo libro aggiunto alla lista sarà /catalog/book/3.
  • catalog/author/<id> — Vista di dettaglio per uno specifico autore con un campo primario <id>.  Per esempio l'URL per l'11esimo autore /catalog/author/11.

I primi tre URL restituiranno la pagina di indice, l'elenco di libri e l'elenco di autori. Questi URL non codificano alcuna informazione aggiuntiva e le query che prelevano i dati dal database saranno sempre le stesse. Tuttavia, i risultati restituiti dalle query dipendono dal contenuto del database.

Al contrario, gli ultimi due URL mostreranno informazioni dettagliate su uno specifico libro o autore. Questi URL codificano l'identità dell'oggetto da visualizzare (rappresentato da <id>. Il mappatore URL estrarrà le informazioni codificate e le passerà alla vista e la vista determinerà dinamicamente quali informazioni ottenere dal database. Codificando le informazioni nell'URL useremo un singolo set di una mappatura url, una vista e un template per gestire tutti i libri (o gli autori).

Note: Con Django, puoi costruire i tuoi URL come richiesto, puoi codificare le informazioni nel corpo dell'URL come mostrato sopra, o includere i parametri GET nell'URL, per esempio /book/?id=6. Qualunque approccio tu usi, gli URL dovrebbero essere mantenuti puliti, logici e leggibili, come raccomandato dagli standard W3C. La documentazione di Django consiglia di codificare le informazioni nel corpo dell'URL per ottenere una migliore progettazione dell'URL

Come accennato nella panoramica, il resto di questo articolo descrive come costruire la pagina indice.

Creare una index page

La prima pagina che creeremo è la pagina indice (catalogo/). La pagina indice includerà alcuni HTML statici, insieme ai "conteggi" generati di diversi record nel database. Per fare questo, creeremo una mappatura URL, una vista e un modello.

Note: Vale la pena prestare molta attenzione in questa sezione. La maggior parte delle informazioni si applica anche alle altre pagine che creeremo.

URL mapping

quando abbiamo creato lo scheletro del website,abbiamo aggiornato il file locallibrary/urls.py per garantire che ogni volta che un URL che inizia con catalog/  viene ricevuto, il modulo URLConf in catalog.urls elaborerà la sottostringa rimanente.

Il seguente codice da locallibrary/urls.py include il modulo catalog.urls:

urlpatterns += [
    path('catalog/', include('catalog.urls')),
]

Note: Ogni volta che Django incontra la funzione di importazione django.urls.include (), divide la stringa URL al carattere finale designato e invia la sottostringa rimanente al modulo URLconf incluso per un'ulteriore elaborazione.

Abbiamo anche creato un placeholder file per l'URLConf, chiamato /catalog/urls.py. Aggiungi il seguente codice a quel file:

urlpatterns = [
    path('', views.index, name='index'),
]

la funzione path()definisce:

  • Un pattern URL, che è una stringa vuota: ''. Discuteremo i pattern URL in dettaglio quando lavoreremo sulle altre visualizzazioni.
  • Una funzione di view che verrà chiamata se il pattern URL viene trovato: views.index,  che è la funzione nominata index() nel file views.py

La funzione path() specifica anche un parametro name, che è un identificatore univoco per questa particolare mappatura degli URL. È possibile utilizzare il nome per "invertire" il mapper, ovvero creare dinamicamente un URL che punta alla risorsa che il programma di mappatura è progettato per gestire. Ad esempio, possiamo usare il parametro name per collegarci alla nostra home page da qualsiasi altra pagina aggiungendo il seguente link in un template:

<a href="{% url 'index' %}">Home</a>.

Note: Potremmo anche mettere un link statico  <a href="/catalog/">Home</a>), ma se in futuro cambiassimo il pattern della home page, per esempio, in/catalog/index) i templates non si collegheranno più correttamente. L'utilizzo di una mappatura URL invertita è molto più flessibile e robusto.

View (function-based)

Una vista è una funzione che elabora una richiesta HTTP, recupera i dati richiesti dal database, esegue il rendering dei dati in una pagina HTML utilizzando un modello HTML e quindi restituisce l'HTML generato in una risposta HTTP per far visualizzare la pagina all'utente. La vista dell'indice segue questo modello — raccoglie informazioni sul numero di Book, BookInstance, BookInstance disponibili, e Author presenti nel database, e passa tali informazioni a un modello per la visualizzazione.

Apri catalog/views.py e nota che il file già importa la funzione di shortcut render() per generare un file HTML usando un template e i dati: 

from django.shortcuts import render

# Create your views here.

Incolla le seguenti righe nella parte inferiore del file:

from catalog.models import Book, Author, BookInstance, Genre

def index(request):
    """View function for home page of site."""

    # Generate counts of some of the main objects
    num_books = Book.objects.all().count()
    num_instances = BookInstance.objects.all().count()
    
    # Available books (status = 'a')
    num_instances_available = BookInstance.objects.filter(status__exact='a').count()
    
    # The 'all()' is implied by default.    
    num_authors = Author.objects.count()
    
    context = {
        'num_books': num_books,
        'num_instances': num_instances,
        'num_instances_available': num_instances_available,
        'num_authors': num_authors,
    }

    # Render the HTML template index.html with the data in the context variable
    return render(request, 'index.html', context=context)

La prima riga importa le classi del modello che useremo per accedere ai dati in tutte le nostre visualizzazioni.

La prima parte della funzione vista recupera il numero di record usando l'attributo objects.all() sulle classi del model. inoltre prende una lista di oggetti BookInstance che hanno il valore 'a' (Available) nel campo status. Ulteriori informazioni sull'accesso ai dati Django Tutorial Part 3: Using models > Searching for records.

Alla fine della funzione di visualizzazione, chiamiamo la funzione render () per creare una pagina HTML e restituire la pagina come risposta. Questa funzione di scelta rapida include una serie di altre funzioni per semplificare un caso d'uso molto comune. La funzione render () accetta i seguenti parametri:

  • L'oggetto request iniziale, che è una HttpRequest.
  • Un template HTML con dei placeholders per i dati.
  • Una variabile di context variable, che è un dizionario Python, contenente i dati da inserire nei segnaposto.

Approfondiremo context e templates nella prossima sezione. Iniziamo a creare il nostro modello in modo che possiamo effettivamente mostrare qualcosa all'utente!

Template

Un template è un file di testo che definisce la struttura o il layout di un file (come una pagina HTML), using placeholders to represent actual content. utilizzando segnaposti per rappresentare il contenuto effettivo. Django cercherà automaticamente i template in una directory chiamata 'templates' nella tua applicazione. Ad esempio, nella vista index che abbiamo appena aggiunto, la funzione render() si aspetterà di trovare il file index.html in /locallibrary/catalog/templates/ e solleverà un errore se il file non è presente. Puoi eseguire un controlo salvando i cambiamenti precedenti ed accedendo a 127.0.0.1:8000 col tuo - verrà mostrato un messaggio di errore: "TemplateDoesNotExist at /catalog/", ed altri dettagli.

Note: Sulla base del file delle impostazioni del progetto, Django cercherà i template in un numero di punti, cercando di default nelle applicazioni installate. Puoi trovare ulteriori informazioni su come Django trova i template e su quali formati di modello supporta sulla sezione Templates della documentazione Django.

Estendere i templates

Il template dell'indice richiede un markup HTML standard per la testa e il corpo, insieme alle sezioni di navigazione per collegarsi alle altre pagine del sito che non abbiamo ancora creato e alle sezioni che visualizzano il testo introduttivo e i dati del libro. Gran parte della struttura HTML e di navigazione sarà la stessa in ogni pagina del nostro sito. Invece di duplicare il codice su ogni pagina, puoi usare il linguaggio di template di Django per dichiarare un template di base, e quindi estenderlo per sostituire solo i bit che sono diversi per ogni pagina specifica.

Il seguente frammento di codice è un modello di base di esempio da un file base_generic.html. L'esempio include HTML comune con sezioni per un titolo, una barra laterale e il contenuto principale contrassegnati con i tag del blocco di nome e del modello di endblock, mostrati in grassetto. È possibile lasciare i blocchi vuoti o includere il contenuto predefinito da utilizzare durante il rendering delle pagine derivate dal modello.

Note: I tag Template sono funzioni che è possibile utilizzare in un Template per scorrere gli elenchi, eseguire operazioni condizionali in base al valore di una variabile e così via. Oltre ai tag del template, la sintassi del modello consente di fare riferimento alle variabili passate nel template dalla vista e utilizzare i filtri dei template per formattare le variabili (ad esempio, per convertire una stringa in lettere minuscole).

<!DOCTYPE html>
<html lang="en">
<head>
  {% block title %}<title>Local Library</title>{% endblock %}
</head>
<body>
  {% block sidebar %}<!-- insert default navigation text for every page -->{% endblock %}
  {% block content %}<!-- default content text (typically empty) -->{% endblock %}
</body>
</html>

Quando definiamo un template per una particolare vista, per prima cosa specifichiamo il template di base usando il tag extends  — vedere il codice di esempio sotto. Quindi dichiariamo quali sezioni del template vogliamo sostituire (se ce ne sono), usando le sezioni block/endblock come nel template di base. 

Ad esempio, il frammento di codice qui sotto mostra come usare il template tag extends ed effettuare un override del block content. L'HTML generato includerà il codice e la struttura definiti nel template di base, incluso il contenuto di default che hai definito nel blocco title, ma il nuovo blocco al posto di quello di default content.

{% extends "base_generic.html" %}

{% block content %}
  <h1>Local Library Home</h1>
  <p>Welcome to LocalLibrary, a website developed by <em>Mozilla Developer Network</em>!</p>
{% endblock %}

Template di base della libreria locale

Utilizzeremo il seguente snippet di codice come modello di base per il sito Web di LocalLibrary. Come puoi vedere, contiene del codice HTML e definisce i blocchi per titolo, barra laterale e contenuto. Abbiamo un titolo predefinito e una barra laterale predefinita con collegamenti a elenchi di tutti i libri e gli autori, entrambi racchiusi in blocchi per essere facilmente modificati in futuro.

Note: Introduciamo anche due ulteriori tag modello: url e load static. Questi tag verranno spiegati nelle seguenti sezioni.

Crea un nuovo file base_generic.html in /locallibrary/catalog/templates/ e copia il codice sotto nel file:

<!DOCTYPE html>
<html lang="en">
<head>
  {% block title %}<title>Local Library</title>{% endblock %}
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
  <!-- Add additional CSS in static file -->
  {% load static %}
  <link rel="stylesheet" href="{% static 'css/styles.css' %}">
</head>
<body>
  <div class="container-fluid">
    <div class="row">
      <div class="col-sm-2">
      {% block sidebar %}
        <ul class="sidebar-nav">
          <li><a href="{% url 'index' %}">Home</a></li>
          <li><a href="">All books</a></li>
          <li><a href="">All authors</a></li>
        </ul>
     {% endblock %}
      </div>
      <div class="col-sm-10 ">{% block content %}{% endblock %}</div>
    </div>
  </div>
</body>
</html>

Il template include CSS da Bootstrap per migliorare il layout e la presentazione della pagina HTML. L'uso di Bootstrap (o di un altro framework web sul lato client) è un modo rapido per creare una pagina attraente che si mostra bene su diverse dimensioni dello schermo.

Il modello di base fa anche riferimento a un file css locale (styles.css) che fornisce uno stile aggiuntivo. Crea un file styles.css in / locallibrary / catalog / static / css / e incolla il seguente codice nel file:

.sidebar-nav {
    margin-top: 20px;
    padding: 0;
    list-style: none;
}

Il template di index

Crea un nuovo file HTML index.html in /locallibrary/catalog/templates/ and paste the following code in the file. Questo codice estende il nostro modello di base sulla prima riga, quindi sostituisce il blocco di content predefinito per il modello. 

{% extends "base_generic.html" %}

{% block content %}
  <h1>Local Library Home</h1>
  <p>Welcome to LocalLibrary, a website developed by <em>Mozilla Developer Network</em>!</p>
  <h2>Dynamic content</h2>
  <p>The library has the following record counts:</p>
  <ul>
    <li><strong>Books:</strong> {{ num_books }}</li>
    <li><strong>Copies:</strong> {{ num_instances }}</li>
    <li><strong>Copies available:</strong> {{ num_instances_available }}</li>
    <li><strong>Authors:</strong> {{ num_authors }}</li>
  </ul>
{% endblock %}

Nella sezione Dynamic content  dichiariamo i placeholders (variabili del template) per le informazioni dalla view che vogliamo includere. Le variabili sono racchiuse tra parentesi graffe, come mostrato in grassetto nel codice di esempio. 

Note: È possibile riconoscere facilmente variabili di template e tag di template (funzioni) - le variabili sono racchiuse tra doppie parentesi ({{ num_books }}), e i tag sono racchiusi tra parentesi graffe singole con segni di percentuale ({% extends "base_generic.html" %}).

La cosa importante da notare qui è che le variabili sono nominate con le chiavi che passiamo nel dizionario context nella funzione render() della nostra view (vedi esempio sotto). Le variabili saranno sostituite con i loro valori associati quando il modello è renderizzato. 

context = {
    'num_books': num_books,
    'num_instances': num_instances,
    'num_instances_available': num_instances_available,
    'num_authors': num_authors,
}

return render(request, 'index.html', context=context)

Referenziare file statici nei templates

È probabile che il tuo progetto utilizzi risorse statiche, inclusi JavaScript, CSS e immagini. Perché la posizione di questi file potrebbe non essere nota (o potrebbe cambiare) Django ti consente di specificare la posizione nei tuoi modelli rispetto alle impostazioni globali di STATIC_URL. Lo scheletro del website imposta il valore di STATIC_URL predefinito a '/static/', ma potresti scegliere di ospitarli su una rete di distribuzione dei contenuti o altrove.

All'interno del modello chiami per la prima volta il tag del modello load che specifica "statico" per aggiungere la libreria modello, come mostrato nell'esempio di codice seguente. È quindi possibile utilizzare il tag del template static e specificare l'URL relativo al file richiesto.

<!-- Add additional CSS in static file --> 
{% load static %} 
<link rel="stylesheet" href="{% static 'css/styles.css' %}">

Puoi anche aggiungere una immagine allo stesso modo, per esempio:

{% load static %}
<img src="{% static 'catalog/images/local_library_model_uml.png' %}" alt="UML diagram" style="width:555px;height:540px;">

Note: Gli esempi sopra specificano dove si trovano i file, ma Django non li serve per impostazione predefinita. Abbiamo configurato il web server di sviluppo per servire i file modificando il mapper URL globale (/locallibrary/locallibrary/urls.py) quando abbiamo creato lo scheletro del website, ma è comunque necessario abilitare il file serving in produzione. Lo vedremo più tardi.

Per maggiori informazioni sul lavoro con file statici vedere utilizzare static files.

Collegarsi agli URLs

Il modello di base sottostante ha introdotto il tag URL.

<li><a href="{% url 'index' %}">Home</a></li> 

Questo tag accetta il nome di una funzione path() chiamata in urls.py e i valori per qualsiasi argomento che la vista associata riceverà da quella funzione e restituisce un URL che è possibile utilizzare per collegarsi alla risorsa.

Configurare dove trovare i templates

Devi indicare a Django dove cercare i tuoi template nella cartella dei template. Per fare ciò, aggiungi la directory templates all'oggetto TEMPLATES modificando il file settings.py come mostrato in grassetto nel seguente esempio di codice:

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',
            ],
        },
    },
]

Come viene renderizzato?

A questo punto abbiamo creato tutte le risorse necessarie per visualizzare la pagina indice. Esegui il serve (python3 manage.py runserver) e apri http://127.0.0.1:8000/ nel browser. Se tutto è configurato correttamente, il tuo sito dovrebbe apparire come il seguente screenshot.

Index page for LocalLibrary website

Note: I link All books e All authors non funzioneranno ancora perché i percorsi, le viste e i modelli per tali pagine non sono definiti. Abbiamo appena inserito i segnaposto per quei link nel template base_generic.html.

Prova tu

Ecco un paio di attività per testare la tua familiarità con le query, le viste e i modelli del modello.

  1. Il base template della libreria include un blocco title. Effettua un override nell' index template e crea un nuovo titolo per la pagina.

    Consiglio: La sezione Extending templates mostra come creare blocchi ed estendere blocchi in altri template.

  2. Modifica la view per generare conteggi per i genres e books che contengono una parola particolare (maiuscole e minuscole) e passano i risultati a context. Lo realizzi in un modo simile alla creazione e all'utilizzo di num_books e num_instances_available. Dopo fai un update dell' index template per includere le variabili.

Sommario

Abbiamo appena creato la home page del nostro sito: una pagina HTML che visualizza un numero di record dal database e collegamenti ad altre pagine ancora da creare. Lungo il percorso abbiamo appreso informazioni fondamentali sui mappatori url, le viste, l'interrogazione del database con i modelli, il passaggio di informazioni a un modello da una vista e la creazione e l'estensione di modelli. Nel prossimo articolo svilupperemo questa conoscenza per creare le restanti quattro pagine del nostro sito web.

Vedi anche

 

In questo modulo

 

Tag del documento e collaboratori

Hanno collaborato alla realizzazione di questa pagina: mdnwebdocs-bot, mattiatoselli
Ultima modifica di: mdnwebdocs-bot,