Как создать отношения на поле модели с тремя разными моделями в django?

Простой глупый вопрос У меня есть модель Exam, которая содержит поле Subject, которое я хочу связать с 3 или 4 или даже 5 предметами, как внешний ключ связать один с другим.


# 1 type
class Math(models.Model):
    id = models.CharField(primary_key=True, max_length=200, blank=True)
    chapter = models.ForeignKey(Chapters, on_delete=models.CASCADE)
    name = models.CharField(max_length=250)
    marks_contain = models.IntegerField(default=10)
    question = RichTextUploadingField()
    hint = RichTextUploadingField()
    created_at = models.DateTimeField(auto_now_add=True, blank=True)

# 2 type
class Science(models.Model):
    id = models.CharField(primary_key=True, max_length=200, blank=True)
    chapter = models.ForeignKey(Chapters, on_delete=models.CASCADE)
    name = models.CharField(max_length=250)
    marks_contain = models.IntegerField(default=10)
    question = RichTextUploadingField()
    hint = RichTextUploadingField()
    created_at = models.DateTimeField(auto_now_add=True, blank=True)

# 3 type
class Computer(models.Model):
    id = models.CharField(primary_key=True, max_length=200, blank=True)
    chapter = models.ForeignKey(Chapters, on_delete=models.CASCADE)
    name = models.CharField(max_length=250)
    marks_contain = models.IntegerField(default=10)
    question = RichTextUploadingField()
    hint = RichTextUploadingField()
    created_at = models.DateTimeField(auto_now_add=True, blank=True)

class Exam(models.Model):
    id = models.AutoField(primary_key=True)
    created_at = models.DateTimeField(auto_now_add=True, blank=True)
    name = models.CharField(max_length=255)
    subject = models.ForeignKey([Math, Science, Computer])  # I want to do something like this

Я знаю, что это невозможно с иностранным ключом, но какой способ сделать такие вещи?

Это возможно с ManyToMany, но вы должны создать новую модель:

from django.utils.module_loading import import_string

class Subject(models.Model):
    class_name = models.CharField(...)
    
    def get_class(self):
        return import_string(f"app_name.models.{self.class_name}")

class Exam(...):
    ...
    subject = models.ManyToManyField(Subject, default=None, blank=True)

Затем просто создайте Subject объект для каждой модели, которая вам нужна, с class_name точно таким же именем, как у вашего __class__ объекта, т.е. Subject.objects.create(class_name="Math"). Затем замените app_name на имя вашего приложения, внутри которого находится models.py.

Если вам нужен реальный класс из класса Subject, просто вызовите subject.get_class(), и вы получите объект: <class 'app_name.models.Math'>.

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