Chaves estrangeiras
Parte da seção Models e o Admin do Journey de Django da Coddy. Lição 16 de 23.
Dois dos seus livros são de Jane Austen, e o nome dela está digitado nos dois: corrija um erro de digitação e você terá que corrigi-lo duas vezes. Mantenha cada autora uma única vez, em uma tabela própria, e faça cada livro apontar para sua autora. Esse ponteiro é uma ForeignKey. Um Loan, um livro que você emprestou a um amigo, apontaria para o livro:
class Loan(models.Model):
book = models.ForeignKey(Book, on_delete=models.PROTECT)
friend = models.CharField(max_length=100)
lent_on = models.DateField()A coluna armazena o id do livro, book_id; em Python, loan.book é o próprio Book. Muitos empréstimos podem apontar para um livro: uma relação muitos para um.
on_delete é obrigatório: ele determina o que acontece com os empréstimos quando o livro é excluído. CASCADE também os exclui, PROTECT impede a exclusão do livro, e SET_NULL esvazia o campo, que então precisa de null=True.
Um modelo Author está pronto, e seu __str__ é o nome, então {{ book.author }} continua funcionando nos seus templates.
Desafio
MédioEm books/models.py, altere Book.author de texto para um link para Author. Quando um autor for excluído, seus livros também serão excluídos.
Pressione Run e abra a aba Data: books.Author contém os seis autores, e as linhas dos livros contêm os IDs deles.
Experimente você mesmo
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 as lições de Models e o Admin
Pratique por conta própria: Playground de Django