簡體   English   中英

在 Django 中創建學生和班級之間的關系

[英]Creating relationship between Student and Class in Django

我正在嘗試創建模型,在其中我可以在 Students 和 ClassName 表之間建立關系,以便我可以讓所有用戶使用 ClassName.objects.get() 和 ClassName 使用 Student.objects.get() 方法。 我完全被困在這里。 我應該向 Student 模型添加更多字段嗎?

from django.contrib.auth.models import AbstractUser
from django.db import models


# Create your models here.
class User(AbstractUser):
    pass


class ClassName(models.Model):
    grade = models.IntegerField()
    section = models.CharField(max_length=1)

    def __str__(self):
        return f"{self.grade} - {self.section}"


class Student(models.Model):
    first_name = models.CharField(max_length=124, null=False)
    middle_name = models.CharField(max_length=124, default='')
    last_name = models.CharField(max_length=124, null=False)
    name = models.CharField(max_length=124, default=f"{first_name} {middle_name} {last_name}")
    father_name = models.CharField(max_length=124, null=False)
    phone_number = models.CharField(max_length=20, null=False)
    date_of_birth = models.DateField()
    national_id= models.CharField(max_length=15, null=False)
    student_class = models.ForeignKey(ClassName, on_delete=models.DO_NOTHING)

    def __str__(self):
        return f"{self.first_name} {self.middle_name} {self.last_name}"

我正在嘗試找到一種方法來讓所有用戶使用 ClassName.objects.get() 和 ClassName 使用 Student.objects.get() 方法。

所以看起來你試圖建立的是用戶和類之間many-to-many (m2m)關系。 這是有道理的,因為一個用戶注冊了多個班級,每個班級都有多名學生參加。

然后您決定創建自己的用戶模型,這也很有意義,因為它為將來可能對代碼庫進行更改打開了大門,而無需在數據庫上執行有風險的手動操作。

您擴展AbstractUser 現在花一分鍾去檢查一下 Django 代碼庫AbstractUser有哪些屬性和方法: >> AbstractUser <<

你可以看到它帶有usernamefirst_namelast_nameemailis_staffis_active等。所以這一切都已經內置在 Django 中,如果你使用這個模型作為基礎(你應該)你不需要重新聲明所有這些屬性。

現在問問自己:每個用戶可以代表多少學生? 通常答案應該是“只有 1”,所以這告訴您在用戶和學生之間您可能想要one-to-one關系。

因此,回顧一下,您需要一個與Student模型具有一對一關系的User模型,然后您需要StudentClassName之間的 m2m 關系。 讓我們看看如何實現它:

# User and Student
class User(AbstractUser):
    middle_name = models.CharField(max_length=124, default='')
    father_name = models.CharField(max_length=124, null=False)
    phone_number = models.CharField(max_length=20, null=False)
    date_of_birth = models.DateField()
    national_id= models.CharField(max_length=15, null=False)

class Student(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="student")

現在您可能注意到您的原始實現中缺少某些字段以及我如何將其他一些字段從Student移至User

我沒有包括在聲明User時繼承的AbstractUser模型中已經存在的一些字段,因為您已經可以訪問這些字段。 因此,例如,如果您要執行:

user = User.objects.get(id=1) 
print(user.first_name)

這會很好用。

我將Student字段移到User的原因是因為這些是屬於User的屬性。 例如,如果你想存儲average_grade那么它就屬於Student模型。 例如father_name可能屬於Student模型。 假設以后你想添加一個Teacher模型,我無法想象教師必須提供他們父親的名字。 但我會讓你決定的! 有關這方面的更多信息,您可以查看我之前寫過的關於您嘗試實現的特定模型結構的答案

現在讓我們看看StudentClassName之間的 m2m 關系。 為此,我強烈建議您閱讀一些有關數據庫和數據庫關系的介紹性材料。 多對多關系是最難理解的,在繼續進行 Django 項目之前,您可能需要花一些時間來理解它。

您可以觀看此視頻,了解許多重要的數據庫概念的摘要。 它在過去幫助過我。

以下是您將如何實施它:

class Student(models.Model)
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="student")
    class_names = models.ManyToManyField(ClassName, related_name="students")

class ClassName(models.Model):
    grade = models.IntegerField()
    section = models.CharField(max_length=1)

我建議您閱讀關於多對多關系的非常好的 django 文檔,以了解您可以使用它們做什么。

簡單來說,這意味着每個Student可以有多個ClassName ,每個ClassName可以有多個Student

您可以從雙方操縱這種關系。 例如:

class_name_1 = ClassName.objects.get(id=1)
class_name_2 = ClassName.objects.get(id=2)
user.class_names.add(class_name_1)
user.class_names.add(class_name_2)
print(user.class_names.all()). # will print: [class_name1, class_name2]

print(class_name_1.students.all()). # will print: [user, ]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM