Как правильно назначить сквозной атрибут в Django?

Я просто искал документацию, чтобы иметь возможность изменить промежуточную таблицу, но когда я ее реализую, у меня возникают проблемы:

https://docs.djangoproject.com/en/2.0/topics/db/models/

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

class Item(models.Model):
     name = models.TextField()
     def __str__(self):
          return self.name

class Category(models.Model):
    name = models.CharField(max_length=50,null=True)
    items = models.ManyToManyField(Item, related_name='categories')
    def __str__(self):
       return self.name

class Professor(models.Model):
    name = models.CharField(max_length=50,null=True)
    categories = models.ManyToManyField(Category, related_name='professors')
    def __str__(self):
       return self.name

class Student(models.Model):
    name = models.CharField(max_length=50,null=True)
    professors = models.ManyToManyField(Professor, related_name='students')
    def __str__(self):
       return self.name

У каждого студента есть профессор (и), эти профессора, в свою очередь, имеют связанные категории вопросов, а каждая категория вопросов имеет связанные вопросы.

Я хочу изменить промежуточную таблицу student_professor добавить поле, в котором, когда ученик оценивает учителя, это заносится в базу данных. Я попробовал это с:

class Professor(models.Model):
    name = models.CharField(max_length=50,null=True)
    categories = models.ManyToManyField(Category, related_name='professors')
    def __str__(self):
        return self.name

class Student(models.Model):
    name = models.CharField(max_length=50,null=True)
    professors = models.ManyToManyField(Professor, related_name='students',through='Studentprofesor' )
    def __str__(self):
        return self.name

class Studentprofesor(models.Model):
    student = models.ForeignKey(Student, on_delete=models.CASCADE)
    professor =  models.ForeignKey(Professor, on_delete=models.CASCADE)
    tested = models.BooleanField(default=False)

Миграция работает без проблем, и в базе данных я получаю промежуточную таблицу student_professor с полями, которые я назначил в модели (поле tested).

Но когда я вхожу в панель администрирования и создаю учащегося, у меня нет возможности назначить учителя учащемуся (если я запускаю код, который у меня есть в первом блоке, то есть без изменения промежуточной таблицы, если я можете назначить это).

Почему это происходит и как это можно исправить?

1 ответ

Решение

Это по замыслу. Django не может автоматически сгенерировать виджет для ManyToMany отношения, которые используют through таблица из-за необходимости дополнительных данных (tested в твоем случае). Из Django документов:

Когда вы указываете промежуточную модель, используя аргумент through для ManyToManyField, администратор не будет отображать виджет по умолчанию. Это связано с тем, что для каждого экземпляра этой промежуточной модели требуется больше информации, чем можно было бы отобразить в одном виджете, а компоновка, требуемая для нескольких виджетов, будет варьироваться в зависимости от промежуточной модели.

Тем не менее, мы все еще хотим иметь возможность редактировать эту информацию в строке. К счастью, это легко сделать с помощью встроенных моделей администратора.

Лучше всего создать модель встроенного администратора, как описано в документации.

Другие вопросы по тегам