Chiavi esterne
Fa parte della sezione Modelli e pannello di amministrazione del percorso Django di Coddy. Lezione 16 di 23.
Due dei tuoi libri sono di Jane Austen e il suo nome è stato digitato in entrambi: correggi un refuso e dovrai correggerlo due volte. Mantieni ogni autore una sola volta, in una tabella dedicata, e fai in modo che ogni libro rimandi al proprio autore. Questo riferimento è una ForeignKey. Un Loan, cioè un libro che hai prestato a un amico, rimanderebbe al suo libro:
class Loan(models.Model):
book = models.ForeignKey(Book, on_delete=models.PROTECT)
friend = models.CharField(max_length=100)
lent_on = models.DateField()La colonna memorizza l'id del libro, book_id; in Python, loan.book è il Book stesso. Molti prestiti possono rimandare a un unico libro: una relazione molti-a-uno.
on_delete è obbligatorio: specifica cosa succede ai prestiti quando il loro libro viene eliminato. CASCADE li elimina a sua volta, PROTECT impedisce di eliminare il libro e SET_NULL svuota il campo, che in tal caso richiede null=True.
Un modello Author è già pronto e il suo __str__ restituisce il nome, quindi {{ book.author }} continua a funzionare nei tuoi template.
Sfida
MedioIn books/models.py, cambia Book.author da testo a un collegamento a Author. Quando un autore viene eliminato, anche i suoi libri vengono eliminati.
Premi «Esegui» e fai clic su Dune: la sua pagina riporta ancora «di Frank Herbert».
Provalo tu
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
class Meta:
ordering = ["name"]
def __str__(self):
return self.name
class Book(models.Model):
class Genre(models.TextChoices):
FICTION = "fiction", "Fiction"
SCIFI = "scifi", "Science fiction"
MYSTERY = "mystery", "Mystery"
HISTORY = "history", "History"
title = models.CharField(max_length=200)
author = models.CharField(max_length=100)
year = models.IntegerField()
price = models.DecimalField(max_digits=6, decimal_places=2)
is_read = models.BooleanField(default=False)
finished = models.DateField(null=True, blank=True)
summary = models.TextField(blank=True)
genre = models.CharField(max_length=20, choices=Genre, default=Genre.FICTION)
class Meta:
ordering = ["title"]
def __str__(self):
return f"{self.title} by {self.author}"
Tutte le lezioni di Modelli e pannello di amministrazione
Esercitati da solo: Playground Django