Questa traduzione è incompleta. Collabora alla traduzione di questo articolo dall’originale in lingua inglese.

Questo articolo mostra come definire dei modelli per il sito della LocalLibrary. Spiega cos'è un modello, come viene dichiarato e alcuni dei principali tipi di campo. Mostra anche brevemente alcuni dei principali modi in cui è possibile accedere ai dati del modello.

Prerequisiti: Django Tutorial Part 2: Creating a skeleton website.
Obbiettivi: Essere in grado di progettare e creare i propri modelli, scegliendo i campi in modo appropriato.

Panoramica

Le applicazioni web Django accedono e gestiscono i dati tramite oggetti Python denominati modelli. I modelli definiscono la struttura dei dati memorizzati, inclusi i tipi di campo e possibilmente anche la loro dimensione massima,valori predefiniti, opzioni dell'elenco di selezione, testo di aiuto per la documentazione, testo dell'etichetta per i moduli, ecc. La definizione del modello è indipendente dal database sottostante: è possibile sceglierne uno tra i diversi come parte delle impostazioni del progetto. Una volta scelto il database che si desidera utilizzare, non è necessario interrogarlo direttamente, basta scrivere la struttura del modello e altro codice, e Django gestirà tutto il lavoro sporco di comunicazione con il database.

Questo tutorial mostra come definire e accedere ai modelli per la LocalLibrary website.

Definire i modelli per la LocalLibrary

Prima di saltare e iniziare a codificare i modelli, vale la pena dedicare alcuni minuti a pensare a quali dati dobbiamo memorizzare e alle relazioni tra i diversi oggetti.

Sappiamo che abbiamo bisogno di memorizzare informazioni sui libri (titolo, sommario, autore, lingua scritta, categoria, ISBN) e che potremmo avere più copie disponibili (con ID unico globale, stato di disponibilità, ecc.). Potremmo aver bisogno di memorizzare più informazioni sull'autore oltre al loro nome e potrebbero esserci più autori con nomi uguali o simili. Vogliamo essere in grado di ordinare le informazioni in base al titolo del libro, autore, lingua scritta e categoria.

Quando si progettano i modelli, è logico disporre di modelli separati per ogni "oggetto" (gruppo di informazioni correlate). In questo caso gli oggetti ovvi sono libri, istanze di libri e autori

Potresti anche voler utilizzare i modelli per rappresentare delle opzioni per un elenco di selezione (ad esempio, come un elenco a discesa), piuttosto che codificare le scelte nel sito stesso - questo è consigliato quando tutte le opzioni non sono note in anticipo o potrebbero essere modificate. I candidati ovvi per i modelli in questo caso includono il genere di libri (ad esempio Science Fiction, Poesia francese, ecc.) e la lingua (inglese, francese, giapponese).

Una volta che abbiamo deciso i nostri modelli e il nostro campo, dobbiamo pensare alle relazioni. Django ti permette di definire relazioni che sono uno a uno (OneToOneField), uno a molti (ForeignKey) e molti a molti (ManyToManyField).

Con questo in mente, lo schema di associazione UML qui sotto mostra i modelli che definiremo in questo caso (come schede). Come sopra, abbiamo creato modelli per il libro (i dettagli generici del libro), l'istanza di un libro (lo stato di specifiche copie fisiche del libro disponibile nel sistema) e l'autore. Abbiamo anche deciso di avere un modello per il genere, in modo che i valori possano essere creati / selezionati attraverso l'interfaccia di amministrazione. Abbiamo deciso di non avere un modello per BookInstance: status - abbiamo codificato i valori (LOAN_STATUS) perché non ci aspettiamo che questi cambino. All'interno di ciascuna casella è possibile visualizzare il nome del modello, i nomi dei campi e i tipi, nonché i metodi e i relativi tipi di ritorno.

Il diagramma mostra anche le relazioni tra i modelli, incluse le loro molteplicità. Le molteplicità sono i numeri sul diagramma che mostrano i numeri (massimo e minimo) di ciascun modello che può essere presente nella relazione. Ad esempio, la linea di collegamento tra le caselle mostra che Book e un genere sono correlati. I numeri vicino al modello di genere mostrano che un libro deve avere uno o più generi (quanti ne vuoi), mentre i numeri all'altro capo della riga accanto al modello di libro mostrano che un genere può avere zero o molti libri.

LocalLibrary Model UML

Note: La prossima sezione fornisce un manuale di base che spiega come vengono definiti e utilizzati i modelli. Mentre lo leggi, considera come costruiremo ciascuno dei modelli nel diagramma sopra.

Fondamenti del modello

Questa sezione fornisce una breve panoramica di come viene definito un modello e alcuni dei campi e argomenti di campo più importanti.

Definizione del modello

I modelli vengono generalmente definiti nel file models.py di una applicazione. Sono implementati come sottoclassi di django.db.models.Model, e possono includere campi, metodi e metadati. Il frammento di codice seguente mostra un modello "tipico", denominato MyModelName:

from django.db import models

class MyModelName(models.Model):
    """A typical class defining a model, derived from the Model class."""

    # Fields
    my_field_name = models.CharField(max_length=20, help_text='Enter field documentation')
    ...

    # Metadata
    class Meta: 
        ordering = ['-my_field_name']

    # Methods
    def get_absolute_url(self):
        """Returns the url to access a particular instance of MyModelName."""
        return reverse('model-detail-view', args=[str(self.id)])
    
    def __str__(self):
        """String for representing the MyModelName object (in Admin site etc.)."""
        return self.my_field_name

Nelle sezioni seguenti esploreremo in dettaglio ciascuna funzionalità all'interno del modello:

Campi

Un modello può avere un numero arbitrario di campi, di qualsiasi tipo - ognuno rappresenta una colonna di dati che vogliamo memorizzare in una delle nostre tabelle del database. Ogni record di database (riga) consisterà in uno di ciascun valore di quei campi. Osserviamo l'esempio seguente:

my_field_name = models.CharField(max_length=20, help_text='Enter field documentation')

Il nostro esempio precedente ha un singolo campo chiamato my_field_name, di tipo models.CharField — che significa che questo campo conterrà stringhe di caratteri alfanumerici. I tipi di campo vengono assegnati utilizzando classi specifiche, che determinano il tipo di record utilizzato per memorizzare i dati nel database, insieme ai criteri di convalida da utilizzare quando i valori vengono ricevuti da un form HTML (vale a dire ciò che costituisce un valore valido). I tipi di campo possono anche prendere argomenti che specificano ulteriormente come il campo è memorizzato o può essere utilizzato. In questo caso stiamo dando al nostro campo due argomenti:

  • max_length=20 — Indica che la lunghezza massima di un valore in questo campo è di 20 caratteri.
  • help_text='Enter field documentation' — fornisce un'etichetta di testo da visualizzare per aiutare gli utenti a sapere quale valore fornire quando questo valore deve essere inserito da un utente tramite un form HTML.

Il nome del campo viene utilizzato per fare riferimento ad esso in query e templates. I campi hanno anche un'etichetta, che è specificata come argomento (verbose_name) o dedotto variando in maiuscola la prima lettera del nome della variabile del campo e sostituendo qualsiasi underscore con uno spazio (ad esempio my_field_name avrebbe una etichetta di default My field name).

L'ordine in cui i campi sono dichiarati influenzerà il loro ordine predefinito se un modello viene reso in un modulo (ad esempio nel sito di amministrazione), tuttavia questo ordine può essere sovrascritto.

Argomenti comuni nei campi

I seguenti argomenti comuni possono essere utilizzati per dichiarare molti dei diversi tipi di campo:

  • help_text: Fornisce un'etichetta di testo per i form HTML (ad esempio nel sito di amministrazione), come descritto sopra.
  • verbose_name: Un nome leggibile dall'uomo per il campo utilizzato nelle etichette di campo. Se non specificato, Django dedurrà il nome dettagliato predefinito dal nome del campo.
  • default: Il valore predefinito per il campo. Questo può essere un valore o un oggetto callable, nel qual caso l'oggetto verrà chiamato ogni volta che viene creato un nuovo record.
  • null: Se True, Django memorizzerà i valori bianchi come NULL nel database per i campi dove questo è appropriato (un campo CharField per esempio memorizzerà invece una stringa vuota). Per default è False.
  • blank: Se True, il campo può essere vuoto nelle tue forme. L'impostazione predefinita è False, il che significa che la convalida del modulo di Django ti costringerà a inserire un valore. Spesso usato con null=True , perché se hai intenzione di consentire valori vuoti, vuoi anche che il database sia in grado di rappresentarli in modo appropriato.
  • choices: Un gruppo di scelte per questo campo. Se viene fornito, il widget modulo corrispondente predefinito sarà una casella di selezione con queste scelte al posto del campo di testo standard.
  • primary_key: Se True, imposta il campo corrente come chiave primaria per il modello (una chiave primaria è una colonna di database speciale designata per identificare in modo univoco tutti i diversi record di tabella). Se non viene specificato alcun campo come chiave primaria, Django aggiungerà automaticamente un campo per questo scopo.

Ci sono molte altre opzioni — consultare full list of field options here.

Tipi di campo più comuni

Il seguente elenco descrive alcuni dei tipi di campi più comunemente usati.

  • CharField è usato per definire stringhe di lunghezza fissa di dimensioni medio-piccole. Devi specificare il max_length dei dati memorizzati.
  • TextField viene utilizzato per stringhe di lunghezza arbitraria di grandi dimensioni. Puoi specificare la max_length per il campo, ma questo viene utilizzato solo quando il campo viene visualizzato nei moduli (non viene applicato a livello di database).
  • IntegerField è un campo per la memorizzazione di valori interi (numero intero) e per la convalida di valori immessi come numeri interi nei moduli.
  • DateField e DateTimeField sono utilizzati per storare/rappresentare date e data/time (in Python come oggetti datetime.date e datetime.datetime, rispettivamente). Questi campi possono essere dichiarati con dei parametri (mutualmente esclusivi) auto_now=True (per settare la data odierna automaticamente ogni volta che il modello viene salvato), auto_now_add (per settare la data solo quando il modello viene creato per la prima volta) , e default (per settare una data di default che possa essere sovrascritta dall'utente).
  • EmailField per storare e validare indirizzi mail.
  • FileField e ImageField per uploadare file e immagini rispettivamente (ImageField aggiunge semplicemente ulteriore convalida che il file caricato è un'immagine). Questi hanno parametri per definire come e dove sono memorizzati i file caricati.
  • AutoField tipologia speciale di IntegerField con autoincremento. Una chiave primaria di questo tipo viene automaticamente aggiunta al tuo modello se non ne specifichi esplicitamente una.
  • ForeignKey è usato per specificare una relazione uno-a-molti con un altro modello di database (ad esempio, un'auto ha un produttore, ma un produttore può fare molte automobili). Il lato "uno" della relazione è il modello che contiene la chiave.
  • ManyToManyField è usato per specificare una relazione molti-a-molti (ad esempio un libro può avere diversi generi e ogni genere può contenere diversi libri). Nella nostra app di libreria li useremo in modo molto simile a ForeignKeys, ma possono essere usati in modi più complicati per descrivere le relazioni tra i gruppi. Questi hanno il parametro on_delete per definire cosa succede quando il record associato viene cancellato (ad esempio un valore models.SET_NULL setta il valore a NULL).

Esistono molti altri tipi di campi, compresi i campi per diversi tipi di numeri (interi grandi, interi piccoli, float), booleani, URL, slug, ID univoci e altre informazioni "temporali" (durata, tempo, ecc.) . È possibile visualizzare la full list here.

Metadata

Puoi dichiarare metadata per il tuo Modello utilizzando class Meta, come mostrato sotto.

class Meta:
    ordering = ['-my_field_name']

Una delle funzionalità più utili di questi metadati consiste nel controllare l'ordinamento predefinito dei record restituiti quando si esegue una query sul tipo di modello. A tale scopo, specificare l'ordine di corrispondenza in un elenco di nomi di campi sull'attributo ordering come sopra. L'ordine dipende dal tipo di campo (i campi dei caratteri sono ordinati alfabeticamente, mentre i campi delle date sono ordinati in ordine cronologico). Come mostrato sopra, puoi anteporre il nome del campo al simbolo meno (-) per invertire l'ordine.

Per esempio, se scegliamo un sort dei libri come nell'esempio per default:

ordering = ['title', '-pubdate']

i libri saranno ordinati alfabeticamente per titolo, dalla A alla Z e quindi per data di pubblicazione all'interno di ciascun titolo, dal più recente al più vecchio. Un altro attributo comune è verbose_name, un nome dettagliato per la classe in forma singolare e plurale:

verbose_name = 'BetterName'

Altri attributi utili consentono di creare e applicare nuove "autorizzazioni di accesso" per il modello (le autorizzazioni predefinite vengono applicate automaticamente), consentire l'ordinamento in base a un altro campo o dichiarare che la classe è "astratta" (una classe base per cui non è possibile creare record, e sarà invece derivato da creare altri modelli). Molte altre opzioni di metadati controllano quale database deve essere utilizzato per il modello e come vengono archiviati i dati (questi sono davvero utili solo se è necessario associare un modello a un database esistente).

La lista completa di opzioni per i metadati: Model metadata options (Django docs).

Metodi

Un modello può avere metodi.

In ogni caso, in ogni modello è necessario definire il metodo standard della classe Python __str __ () per restituire una stringa leggibile dall'uomo per ciascun oggetto. Questa stringa viene utilizzata per rappresentare singoli record nel sito di amministrazione (e in qualsiasi altro punto è necessario fare riferimento a un'istanza del modello). Spesso questo restituirà un titolo o un campo nome dal modello.

def __str__(self):
    return self.field_name

Un altro metodo comune da includere nei modelli Django è get_absolute_url (), che restituisce un URL per la visualizzazione di record di modelli individuali sul sito Web (se si definisce questo metodo, Django aggiungerà automaticamente un pulsante "Visualizza sul sito" alle schermate di modifica dei record del modello in il sito di amministrazione). Di seguito viene mostrato un tipico pattern per get_absolute_url ().

def get_absolute_url(self):
    """Returns the url to access a particular instance of the model."""
    return reverse('model-detail-view', args=[str(self.id)])

Note: Supponendo che utilizzerai URLs come /myapplication/mymodelname/2 per visualizzare record individuali per il tuo modello (dove "2" è l'id per un particolare record), dovrai creare un mapper URL per passare la risposta e l'id a una "vista dettagli del modello" (che farà il lavoro richiesto per mostrare il record). la funzione reverse() sopra effettua un "reverse" del tuo url mapper (nel caso sopra nominato 'model-detail-view') per creare un URL nel formato corretto.

Ovviamente per fare questo lavoro devi ancora scrivere la mappatura degli URL, la vista e il template!

Puoi anche definire altri metodi che ti piacciono e chiamarli dal tuo codice o template(a condizione che non prendano alcun parametro).

Manipolazione del modello

Una volta definite le classi del modello, è possibile utilizzarle per creare, aggiornare o eliminare record e per eseguire query per ottenere tutti i record o particolari sottoinsiemi di record. Ti mostreremo come farlo nel tutorial quando definiremo le nostre views, ma ecco un breve riassunto.

Creare e modificare record

Per creare un record puoi definire una istanza del modello e poi richiamare save().

# Create a new record using the model's constructor.
record = MyModelName(my_field_name="Instance #1")

# Save the object into the database.
record.save()

Note: Se non hai dichiarato alcun campo come primary_key, al nuovo record ne verrà assegnato automaticamente, con nome del campo id. È possibile interrogare questo campo dopo aver salvato il record precedente, esso avrà valore 1.

È possibile accedere ai campi in questo nuovo record utilizzando la sintassi del punto e modificare i valori. Devi chiamare save () per memorizzare i valori modificati nel database.

# Access model field values using Python attributes.
print(record.id) # should return 1 for the first record. 
print(record.my_field_name) # should print 'Instance #1'

# Change record by modifying the fields, then calling save().
record.my_field_name = "New Instance Name"
record.save()

Ricercare record

È possibile cercare i record che soddisfano determinati criteri utilizzando l'attributo oggetti del modello (fornito dalla classe base).

Note: Spiegare come cercare i record usando il modello "astratto" nei nomi dei campi può generare un po 'di confusione. Nella discussione seguente faremo riferimento a un modello di libro con campi titolo e genere, in cui il genere è anche un modello con un nome di campo singolo.

Possiamo ottenere tutti i record per un modello come QuerySet, usando objects.all (). QuerySet è un oggetto iterabile, ovvero contiene un numero di oggetti che è possibile scorrere.

all_books = Book.objects.all()

filter() ci consente di filtrare il QuerySet restituito per abbinare un testo o un campo numerico specificato a un particolare criterio. Ad esempio, per filtrare i libri che contengono "wild" nel titolo e quindi contarli, potremmo fare quanto segue.

wild_books = Book.objects.filter(title__contains='wild')
number_wild_books = Book.objects.filter(title__contains='wild').count()

I campi da abbinare e il tipo di corrispondenza sono definiti nel nome del parametro del filtro, utilizzando il formato: nome_campo _match_type (notare la doppia underscore tra il titolo e contains sopra). In alto stiamo filtrando il titolo con una corrispondenza che fa distinzione tra maiuscole e minuscole. Esistono molti altri tipi di corrispondenze: icontains (maiuscole / minuscole), iexact (corrispondenza esatta insensibile alle maiuscole / minuscole), exact (corrispondenza esatta case-sensitive) e in, gt (maggiore di), startswith, ecc. consultare la full list.

In alcuni casi è necessario filtrare su un campo che definisce una relazione uno-a-molti con un altro modello (per esempio una ForeignKey). In questo caso è possibile "indicizzare" i campi all'interno del modello correlato con caratteri di underscore doppi aggiuntivi. Quindi, ad esempio, per filtrare i libri con uno specifico genere, dovrai indicizzare al name attraverso il campo genre, come mostrato sotto:

# Will match on: Fiction, Science fiction, non-fiction etc.
books_containing_genre = Book.objects.filter(genre__name__icontains='fiction')

Note: Puoi usare gli underscores (__) per navigare tutti i liveli di relazione che ti servono (ForeignKey/ManyToManyField). Per esempio, un Book che aveva diversi tipi, definiti usando un'ulteriore relazione "di copertura" potrebbe avere un nome di parametro: type__cover__name__exact='hard'.

C'è molto di più che puoi fare con le query, comprese le ricerche all'indietro dai modelli correlati, concatenare i filtri, restituire un insieme più piccolo di valori, ecc. Per ulteriori informazioni, vedere Making queries (Django Docs).

Definire i Models della LocalLibrary

In questa sezione inizieremo a definire i modelli per la libreria. Apri models.py (in /locallibrary/catalog/). Le righe di codice iniziali importano il module models, che conteine la classe di base models.Model che verrà usata dai nostri modelli come classe da cui ereditare.

from django.db import models

# Create your models here.

Modello Genere

Copia il codice del modello Genre mostrato sotto e incollalo alla fine del file models.py. Questo modello viene utilizzato per memorizzare informazioni sulla categoria di libri, ad esempio se si tratta di narrativa o saggistica, storia romantica o militare, ecc. Come menzionato sopra, abbiamo creato il Genere come modello piuttosto che come testo libero o elenco di selezione in modo che i possibili valori possano essere gestiti tramite il database anziché essere codificati.

class Genre(models.Model):
    """Model representing a book genre."""
    name = models.CharField(max_length=200, help_text='Enter a book genre (e.g. Science Fiction)')
    
    def __str__(self):
        """String for representing the Model object."""
        return self.name

Il modello ha un singolo CharField (name), che descrive il genere (Limitato a 200 caratteri e con un help_text. Alla fine del modello definiamo un metodo __str__(), che restituisce semplicemente il nome del genere definito da un particolare record. Nessun nome dettagliato è stato definito, quindi il campo nel form verrà chiamato Name.

Modello libro

Copia il modello di libro in basso e incollalo nuovamente nella parte inferiore del file. Il modello del libro rappresenta tutte le informazioni su un libro disponibile in senso generale, ma non una particolare "istanza" fisica o "copia" disponibile per il prestito. Il modello usa un campo CharField per rappresentare titleisbn (Notare come isbn specifica la sua etichetta come "ISBN" utilizzando il primo parametro senza nome, in caso contrario la label di default sarebbe "Isbn"). Il modello usa TextField per il summary, perchè potrebbe essere un campo abbastanza lungo.

from django.urls import reverse # Used to generate URLs by reversing the URL patterns

class Book(models.Model):
    """Model representing a book (but not a specific copy of a book)."""
    title = models.CharField(max_length=200)

    # Foreign Key used because book can only have one author, but authors can have multiple books
    # Author as a string rather than object because it hasn't been declared yet in the file
    author = models.ForeignKey('Author', on_delete=models.SET_NULL, null=True)
    
    summary = models.TextField(max_length=1000, help_text='Enter a brief description of the book')
    isbn = models.CharField('ISBN', max_length=13, help_text='13 Character <a href="https://www.isbn-international.org/content/what-isbn">ISBN number</a>')
    
    # ManyToManyField used because genre can contain many books. Books can cover many genres.
    # Genre class has already been defined so we can specify the object above.
    genre = models.ManyToManyField(Genre, help_text='Select a genre for this book')
    
    def __str__(self):
        """String for representing the Model object."""
        return self.title
    
    def get_absolute_url(self):
        """Returns the url to access a detail record for this book."""
        return reverse('book-detail', args=[str(self.id)])

Genre è un campo ManyToManyField, in modo che un libro possa avere più generi e un genere possa avere molti libri. L'autore è dichiarato come ForeignKey, quindi ogni libro avrà un solo autore, ma un autore può avere molti libri (in pratica un libro potrebbe avere più autori, ma non in questa implementazione!)

In entrambi i tipi di campo, la classe del modello correlata viene dichiarata come il primo parametro senza nome utilizzando la classe del modello o una stringa contenente il nome del modello correlato. È necessario utilizzare il nome del modello come stringa se la classe associata non è stata ancora definita in questo file prima che venga referenziata! Gli altri parametri di interesse nel campo autore sono null = True, che consente al database di memorizzare un valore Null se nessun autore è selezionato e on_delete = models.SET_NULL, che imposterà il valore dell'autore su Null se l'autore associato al record è cancellato.

Inoltre il modello definisce __str__() , utilizzando il titolo del libro title per rappresentare un record libro Book. L'ultimo metodo, get_absolute_url() ritorna un URL che può essere usato per accedere a un record di dettaglio per questo modello (per farlo funzionare dovremo definire una mappatura URL che abbia il nome book-detail, e definire una view associata ed un template).

Modello BookInstance

Copia il modello mostrato sotto, BookInstance. Esso rappresenta una copia specifica di un libro che potrebbe essere presa in prestito da qualcuno e include informazioni sul fatto che la copia sia disponibile o sulla data in cui è prevista la restituzione, o dettagli sulla versione e un ID univoco per il libro nella libreria.

Alcuni metodi e campi suoneranno familiari. Il modello usa

  • ForeignKey per identificare il Book (ogni book ha possibilità di avere molte copie, ma una copia può avere un solo Book).
  • CharField per rappresentare l'edizione del libro.
import uuid # Required for unique book instances

class BookInstance(models.Model):
    """Model representing a specific copy of a book (i.e. that can be borrowed from the library)."""
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text='Unique ID for this particular book across whole library')
    book = models.ForeignKey('Book', on_delete=models.SET_NULL, null=True) 
    imprint = models.CharField(max_length=200)
    due_back = models.DateField(null=True, blank=True)

    LOAN_STATUS = (
        ('m', 'Maintenance'),
        ('o', 'On loan'),
        ('a', 'Available'),
        ('r', 'Reserved'),
    )

    status = models.CharField(
        max_length=1,
        choices=LOAN_STATUS,
        blank=True,
        default='m',
        help_text='Book availability',
    )

    class Meta:
        ordering = ['due_back']

    def __str__(self):
        """String for representing the Model object."""
        return f'{self.id} ({self.book.title})'

Dichiaramo una ulteriore serie di nuovi campi di altri tipi:

  • UUIDField usato con l' id per impostarlo come primary_key. Questo tipo di campo alloca un valore globalmente univoco per ogni istanza (una per ogni libro che è possibile trovare nella libreria).
  • DateField usato per la data due_back (data in cui il libro dovrebbe riotrnare disponibile dopo essere stato in prestito o in manutenzione). Questo valore può essere blanknull. I metadati del modello (Class Meta) usano questo campo per ordinare i record quando vengono restituiti da una query.
  • status un CharField che definisce una scelta / lista di selezione. Come puoi vedere, definiamo una tupla contenente tuple di coppie chiave-valore e la passiamo all'argomento delle scelte. Il valore in una coppia chiave / valore è un valore di visualizzazione che un utente può selezionare, mentre le chiavi sono i valori che vengono effettivamente salvati se l'opzione è selezionata. Abbiamo anche impostato un valore predefinito di "m" (manutenzione) poiché i libri inizialmente non saranno disponibili prima di essere immagazzinati sugli scaffali.

__str__() rappresenta l'oggetto BookInstance usando una combinazione del suo id univoco e del titolo del libro.

Note: un po' di Python:

  • A partire da Python 3.6, puoi utilizzare la sintassi di interpolazione delle stringhe (anche nota come f-strings): f'{self.id} ({self.book.title})'.
  • in altre versioni di questo tutorial, più vecchie, usavamo una stringa formattata (formatted string), che è un altro modo valido di formattare le stringhe in Python (esempio: '{0} ({1})'.format(self.id,self.book.title)).

Modello Autore

Copia il modello Author sotto il codice esistente in models.py.

Tutti i campi / metodi dovrebbero ora essere familiari. Il modello definisce un autore come un nome, un cognome, una data di nascita e (facoltativo) la data di morte. Specifica che per impostazione predefinita __str __ () restituisce il nome come: cognome e nome nell'ordine. Il metodo get_absolute_url () inverte il mapping degli URL dei dettagli dell'autore per ottenere l'URL per la visualizzazione di un singolo autore.

class Author(models.Model):
    """Model representing an author."""
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    date_of_birth = models.DateField(null=True, blank=True)
    date_of_death = models.DateField('Died', null=True, blank=True)

    class Meta:
        ordering = ['last_name', 'first_name']
    
    def get_absolute_url(self):
        """Returns the url to access a particular author instance."""
        return reverse('author-detail', args=[str(self.id)])

    def __str__(self):
        """String for representing the Model object."""
        return f'{self.last_name}, {self.first_name}'

Rifare le migrazioni del database

Tutti i modelli sono stati creati. Rilanciamo la migrazione del database per aggiungerli effettivamente al database.

python3 manage.py makemigrations
python3 manage.py migrate

Modello del linguaggio — Sfida

Immagina che un benefattore locale doni un certo numero di nuovi libri scritti in un'altra lingua (ad esempio, farsi). La sfida è capire come questi sarebbero meglio rappresentati nel nostro sito web della biblioteca e poi aggiungerli ai modelli.

Considerazioni:

  • "Language" dovrebbe essere associato con Book, BookInstance, o altri objects?
  • I diversi linguaggi dovrebbero essere rappresentati utilizzando un model, una casella di testo o una lista codificata a mano?

Dopo aver deciso, aggiungi il campo. Puoi vedere cosa abbiamo deciso su Github here.

Non dimenticare di rieffettuare le migrazioni dopo ogni cambiamento al tuo modello.

python3 manage.py makemigrations
python3 manage.py migrate

Sommario

In questo articolo abbiamo appreso come sono definiti i modelli, quindi abbiamo utilizzato queste informazioni per progettare e implementare modelli appropriati per il sito Web LocalLibrary.

A questo punto ci distrarremo brevemente dalla creazione del sito e controlleremo il sito di amministrazione di Django. Questo sito ci permetterà di aggiungere alcuni dati alla libreria, che possiamo quindi visualizzare usando le nostre viste e modelli (ancora da creare).

Consulta anche

 

In questo modulo

 

Tag del documento e collaboratori

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