Menu
CoddyTech

외래 키

Coddy Django 여정의 모델과 관리자 섹션에 포함된 레슨. 23개 중 16번째.

책 두 권의 저자가 Jane Austen이고 두 책 모두에 이름을 입력해 두었다면, 오타를 고칠 때 두 번 고쳐야 합니다. 저자별 테이블을 만들어 각 저자를 한 번만 저장하고, 각 책이 해당 저자를 가리키게 하세요. 이 참조가 바로 ForeignKey입니다. 친구에게 빌려준 책을 나타내는 Loan은 해당 책을 가리키게 됩니다.

class Loan(models.Model):
    book = models.ForeignKey(Book, on_delete=models.PROTECT)
    friend = models.CharField(max_length=100)
    lent_on = models.DateField()

열에는 책의 id인 book_id가 저장됩니다. Python에서는 loan.book이 Book 자체입니다. 여러 대출이 하나의 책을 가리킬 수 있습니다. 이것이 다대일 관계입니다.

on_delete는 필수입니다. 책이 삭제될 때 대출 항목에 어떤 일이 일어날지를 지정합니다. CASCADE는 대출 항목도 함께 삭제하고, PROTECT는 책 삭제를 막으며, SET_NULL은 필드를 비웁니다. 이 경우 null=True가 필요합니다.

Author 모델이 준비되어 있고, __str__은 이름을 반환하므로 템플릿의 {{ book.author }}도 계속 작동합니다.

challenge icon

챌린지

중급

books/models.py에서 Book.author를 텍스트에서 Author를 가리키는 링크로 바꾸세요. 작가가 삭제되면 그 작가의 책도 함께 삭제됩니다.

‘실행’을 누르고 Dune을 클릭하세요. 해당 페이지에는 여전히 Frank Herbert의 책이라고 표시됩니다.

직접 해보기

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}"

모델과 관리자의 모든 레슨

직접 연습해 보세요: Django 플레이그라운드