Menu
CoddyTech

المفاتيح الخارجية

جزء من قسم النماذج ولوحة الإدارة في رحلة Django على Coddy. الدرس 16 من 23.

كتابان من كتبك من تأليف 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()

يخزّن العمود معرّف الكتاب، book_id؛ أما في Python، فإن loan.book هو كائن Book نفسه. يمكن لعدة إعارات أن تشير إلى كتاب واحد: علاقة many-to-one.

الخيار 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}"

جميع دروس النماذج ولوحة الإدارة

تدرّب بنفسك: Playground لـ Django