Clés étrangères
Fait partie de la section Modèles et interface d’administration du Journey Django de Coddy. Leçon 16 sur 23.
Deux de tes livres sont de Jane Austen, et son nom est saisi dans les deux : corrige une faute de frappe et tu dois la corriger deux fois. Garde chaque auteur une seule fois, dans sa propre table, et fais pointer chaque livre vers son auteur. Ce pointeur est une ForeignKey. Un Loan, c’est un livre que tu as prêté à un ami ; il pointerait vers son livre :
class Loan(models.Model):
book = models.ForeignKey(Book, on_delete=models.PROTECT)
friend = models.CharField(max_length=100)
lent_on = models.DateField()La colonne stocke l’identifiant du livre, book_id ; en Python, loan.book est le Book lui-même. Plusieurs prêts peuvent pointer vers un seul livre : une relation plusieurs-à-un.
on_delete est obligatoire : il indique ce qui arrive aux prêts lorsque leur livre est supprimé. CASCADE les supprime également, PROTECT empêche la suppression du livre, et SET_NULL vide le champ, qui nécessite alors null=True.
Un modèle Author est prêt, et son __str__ correspond au nom, donc {{ book.author }} continue de fonctionner dans tes modèles.
Défi
MoyenDans books/models.py, remplace le texte de Book.author par un lien vers Author. Lorsqu’un auteur est supprimé, ses livres sont également supprimés.
Appuie sur « Jouer » et clique sur Dune : sa page indique toujours by Frank Herbert.
Essayez vous-même
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}"
Toutes les leçons de Modèles et interface d’administration
3Des pages issues de la base de données
Une liste issue de la base de donnéesUne page pour chaque livreEntraînez-vous par vous-même : Playground Django