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 نفسه. يمكن لعدة سجلات إعارة أن تشير إلى كتاب واحد: وهذه علاقة متعدد إلى واحد.

المعامل on_delete مطلوب: فهو يحدد ما يحدث لسجلات الإعارة عند حذف الكتاب. يحذفها CASCADE أيضًا، ويرفض PROTECT حذف الكتاب، بينما يفرغ SET_NULL الحقل، ما يستلزم عندئذٍ استخدام null=True.

نموذج Author جاهز، و__str__ الخاص به هو الاسم، لذا سيظل {{ book.author }} يعمل في قوالبك.

challenge icon

التحدي

متوسط

في books/models.py، غيّر Book.author من نص إلى رابط إلى Author. عند حذف مؤلف، تُحذف كتبه معه.

اضغط على تشغيل وافتح علامة تبويب البيانات: يحتوي books.Author على المؤلفين الستة، وتحتوي صفوف الكتب على معرّفاتهم.

جرّب بنفسك

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