在添加对象中使用 ManyToMany 字段 raise 需要为字段 "id" 赋值才能使用此多对多关系

Use ManyToMany field in add object raise needs to have a value for field "id" before this many-to-many relationship can be used

我有两个模型:ExamQuestion。每道题都有点,每次考试自动计算

这是我的文件:

#Models.py
class Exam(models.Model):
    questions = models.ManyToManyField(Question)
    title = models.CharField()
class Question(models.Model):
    title = models.CharField()
    answer = models.TextField()
    points = models.PositiveSmallIntegerField()

#Forms.py
class ExamForm(ModelForm):
    class Meta:
        model = Exam
        fields = '__all__'

#Views.py
if form.is_valid():
    new_exam = form.save(commit=False)
    # Some modify goes here. 
    new_exam.save()
    form.save_m2m()
    return redirect('view_exam')

我确实为此定制了 Exam 模型的 save() 方法:

 def save(self, *args, **kwargs):
        self.point = 0
        for question in self.questions:
                self.point += question.point
        super(Exam, self).save(*args, **kwargs)

但是我得到了这个错误:

"<Exam: NewObject>" needs to have a value for field "id" before this many-to-many relationship can be used.

如何在不引发任何错误的情况下执行此操作?

我的目标:对于每一个新创建的试卷,计算本次试题的分值,并将它们放入Exampoints字段中模型。

将可以从数据库中的其他 fields/tables 计算出来的东西保存到模型中绝不是一个好主意,尤其是当这取决于其他模型时。例如,当您在某个阶段创建一个新的 Question 时,很容易忘记更新值。您只会在数据库中出现不一致。

删除您的自定义 save() 方法,因为它不执行任何操作。

如果您想知道总点数,请在 Exam 上添加一个自定义 getter 以动态计算:

#At the first of models.py -> from django.db.models import Sum 
@property
def points(self):
    if self.pk:
       return self.questions.all().aggregate(Sum('points'))['points__sum']
    else:
       return 0

或者用你的总和:

@property
def points(self):
    if self.pk:
        point = 0
        questions = self.questions.all()
        for question in questions :
            point += question.point
        return point
    else:
        return 0

有了这个 属性,您可以在代码的任何地方执行 exam.points,它会是最新的。