Django Models множественные отношения по внешнему ключу

Допустим, у меня есть модель, например,:

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)

Как я могу создать отношение внешнего ключа от module к topic, используя три поля: date, subject и topic_id?

Я хотел бы иметь такой формат, чтобы человеку, вставляющему в базу данных, не приходилось выяснять автогенерируемый id темы перед вставкой в таблицу модуля.

В одной теме много модулей, а в одном предмете много тем.

Измените свои отношения следующим образом:

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()

Если вы измените модель темы на эту, вы сможете подтвердить, что любой subject на topic должен совпадать с 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 key, вам действительно нужно только ограничение unique together, которое вы уже реализовали.

Вернуться на верх