如何在django中正确分配through属性?

时间:2018-05-10 20:09:49

标签: django django-models many-to-many django-database django-intermediate-table

我只是看文档能够更改中间表但是当我实现它时,我遇到了麻烦:

https://docs.djangoproject.com/en/2.0/topics/db/models/#extra-fields-on-many-to-many-relationships

我正在开发一个应用程序,学生可以评估他们的老师,我的模型是:

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 个答案:

答案 0 :(得分:0)

这是设计的。由于需要额外的数据(在您的情况下为ManyToMany),Django无法自动生成使用through表的tested关系的窗口小部件。来自Django docs

  

使用ManyToManyField的through参数指定中间模型时,默认情况下管理员不会显示窗口小部件。这是因为该中间模型的每个实例都需要比单个窗口小部件中显示的信息更多的信息,并且多个窗口小部件所需的布局将根据中间模型而变化。

     

但是,我们仍然希望能够内联编辑该信息。幸运的是,使用内联管理模型很容易做到这一点。

最好的办法是按照文档中的说明创建内联管理模型。