如何将多个 ManytoMany 实例保存到 Django 对象?
How to save multiple ManytoMany instances to a Django object?
我有一个包含多个问题对象的 Django 应用程序。问题和测验通过 ManyToManyField 关联。我想创建 Quiz 对象,以便为每个测验随机分配 3 个问题。
我尝试在我的模型中创建一个保存方法:使用查询集获取 3 个问题,保存测验实例(以保存 ID),将查询集设置为测验并再次保存。我对这个主题的大部分搜索都显示了人们在哪里使用表单来保存 m2m 对象。
更好的是,是否可以使用视图将 3 个问题设置为测验对象?最终这就是我想要到达的地方。用户将在视图中使用 request.GET select LearnGoal,并且此 LearnGoal 将限制将要出现的问题添加到测验。
我的 models.py 到目前为止:
class LearnGoal(models.Model):
goal_name = models.CharField(max_length=12)
goal_description = models.TextField()
class Question(models.Model):
name = models.CharField(max_length=12)
learngoal = models.ForeignKey(LearnGoal, on_delete=models.CASCADE)
q_text = models.TextField()
answer = models.CharField(max_length=12)
class Quiz(models.Model):
"""quiz which will have three questions."""
name = models.CharField(max_length=12)
questions = models.ManyToManyField(Question)
completed = models.DateTimeField(auto_now_add=True)
my_answer = models.CharField(max_length=12)
def save(self, *args, **kwargs):
"""need to create an instance first, for the m2m"""
super(Quiz, self).save(*args, **kwargs)
"""get 3 random questions"""
three_questions = Quiz.objects.all().order_by('?')[0:3]
self.questions.set(three_questions)
super(Quiz, self).save(*args, **kwargs)
我已经尝试了上述代码的一些变体。目前这段代码给出了错误:
'Question' instance expected, got <Quiz: Quiz object (4)>
从行 self.questions.set(five_questions)
如何将多个问题保存到一个测验实例中?
在Quiz.save
方法中,你可以这样做:
class Quiz(models.Model):
...
...
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.add_questions = False
def save(self, *args, **kwargs):
# We need this to prevent updating questions
# on updating the Quiz instance
if self.pk is None:
self.add_questions = True
super().save(*args, **kwargs)
if self.add_questions:
# No need to run save again; M2M relationships are set
# through an intermediate model
self.questions.set(Question.objects.order_by('?')[:3])
请注意,随机排序 (order_by('?')
) 速度很慢,但这是否会影响您完全取决于用例。
我有一个包含多个问题对象的 Django 应用程序。问题和测验通过 ManyToManyField 关联。我想创建 Quiz 对象,以便为每个测验随机分配 3 个问题。
我尝试在我的模型中创建一个保存方法:使用查询集获取 3 个问题,保存测验实例(以保存 ID),将查询集设置为测验并再次保存。我对这个主题的大部分搜索都显示了人们在哪里使用表单来保存 m2m 对象。
更好的是,是否可以使用视图将 3 个问题设置为测验对象?最终这就是我想要到达的地方。用户将在视图中使用 request.GET select LearnGoal,并且此 LearnGoal 将限制将要出现的问题添加到测验。
我的 models.py 到目前为止:
class LearnGoal(models.Model):
goal_name = models.CharField(max_length=12)
goal_description = models.TextField()
class Question(models.Model):
name = models.CharField(max_length=12)
learngoal = models.ForeignKey(LearnGoal, on_delete=models.CASCADE)
q_text = models.TextField()
answer = models.CharField(max_length=12)
class Quiz(models.Model):
"""quiz which will have three questions."""
name = models.CharField(max_length=12)
questions = models.ManyToManyField(Question)
completed = models.DateTimeField(auto_now_add=True)
my_answer = models.CharField(max_length=12)
def save(self, *args, **kwargs):
"""need to create an instance first, for the m2m"""
super(Quiz, self).save(*args, **kwargs)
"""get 3 random questions"""
three_questions = Quiz.objects.all().order_by('?')[0:3]
self.questions.set(three_questions)
super(Quiz, self).save(*args, **kwargs)
我已经尝试了上述代码的一些变体。目前这段代码给出了错误:
'Question' instance expected, got <Quiz: Quiz object (4)>
从行 self.questions.set(five_questions)
如何将多个问题保存到一个测验实例中?
在Quiz.save
方法中,你可以这样做:
class Quiz(models.Model):
...
...
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.add_questions = False
def save(self, *args, **kwargs):
# We need this to prevent updating questions
# on updating the Quiz instance
if self.pk is None:
self.add_questions = True
super().save(*args, **kwargs)
if self.add_questions:
# No need to run save again; M2M relationships are set
# through an intermediate model
self.questions.set(Question.objects.order_by('?')[:3])
请注意,随机排序 (order_by('?')
) 速度很慢,但这是否会影响您完全取决于用例。