Claves foráneas
Parte de la sección Modelos y el panel de administración del Journey de Django de Coddy. Lección 16 de 23.
Dos de tus libros son de Jane Austen, y su nombre está escrito en ambos: corriges un error tipográfico y lo corriges dos veces. Guarda cada autor una sola vez, en su propia tabla, y haz que cada libro apunte a su autor. Ese puntero es una ForeignKey. Un Loan, un libro que le prestaste a un amigo, apuntaría a su libro:
class Loan(models.Model):
book = models.ForeignKey(Book, on_delete=models.PROTECT)
friend = models.CharField(max_length=100)
lent_on = models.DateField()La columna almacena el id del libro, book_id; en Python, loan.book es el propio Book. Muchos préstamos pueden apuntar a un mismo libro: una relación de muchos a uno.
on_delete es obligatorio: indica qué ocurre con los préstamos cuando se elimina su libro. CASCADE también los elimina, PROTECT impide eliminar el libro y SET_NULL vacía el campo, lo que requiere null=True.
El modelo Author está listo y su __str__ es el nombre, así que {{ book.author }} sigue funcionando en tus plantillas.
Desafío
IntermedioEn books/models.py, cambia Book.author de texto a un enlace a Author. Cuando se elimina un autor, sus libros se eliminan con él.
Pulsa Run y abre la pestaña Data: books.Author contiene los seis autores, y las filas de libros contienen sus identificadores.
Pruébalo tú mismo
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}"
Todas las lecciones de Modelos y el panel de administración
3Páginas desde la base de datos
Una lista desde la base de datosUna página para cada libroPractica por tu cuenta: Playground de Django