python-3.x Django为多个外键关系建模

qyzbxkaa  于 2023-01-27  发布在  Python
关注(0)|答案(1)|浏览(117)

假设我有一个模型,例如:

class Topic(models.Model):
    date = models.DateField(null=False, blank=False)
    subject = models.ForeignKey(Subject, blank=False, null=False, on_delete=models.CASCADE)
    topic_id = models.PositiveIntegerField(null=False, blank=False)
    aggregate_difficulty = models.PositiveIntegerField(null=False, blank=False)

    class Meta:

        constraints = [models.UniqueConstraint(fields=["subject", "date", "topic_id"], name="topic_unique")]

我们还有另一个模型,例如:

class Module(models.Model):
    date = models.DateField(null=False, blank=False)
    subject = models.ForeignKey(Subject, blank=False, null=False, on_delete=models.CASCADE)
    topic_id = models.PositiveIntegerField(null=False, blank=False)
    content = models.TextField()
    difficulty = models.PositiveIntegerField(null=False, blank=False)

如何使用以下三个字段创建从moduletopic的外键关系:datesubjecttopic_id
我希望使用这种格式,这样插入数据库的人就不必在插入模块表之前找出自动生成的主题ID。
一个主题有许多模块,一个主题有许多主题。

yr9zkbsy

yr9zkbsy1#

像这样改变你的关系:

class Subject(models.Model):
    ...
    
class Module(models.Model):
    subject = models.ForeightKey('Subject', ..., related_name='modules')

class Topic(models.Model):
    module = models.ForeignKey('Module', ..., related_name='topics')

然后,您可以检查subject是否为topic,如下所示:

topic = Topic.objects.get('<topic-id>')
subject = topic.module.subject

或者查找给定模块的所有主题:

module = Module.objects.get('<module-id>')
topics = module.topics.all()

如果您将主题模型更改为这样,您可以验证topic上的任何subject必须与模块上的subject匹配,如下所示:

from django.core.exceptions import ValidationError

class Topic(models.Model):
    module = models.ForeignKey('Module', ..., related_name='topics')
    subject = models.ForeignKey('Subject', ..., related_name='topics')

    def save(self, *args, **kwargs):
        if self.module.subject != self.subject:
            raise ValidationError('The subject must match the subject on the module!')
        return super().save(*args, **kwargs)

最后,date字段不是另一个模型,所以您不需要foriegn键关系,您实际上只需要一个惟一的together约束,您已经实现了这个约束。

相关问题