问题
I have a django app with several Question objects. Question and Quiz are related through a ManyToManyField. I want to create Quiz objects such that each quiz is randomly assigned 3 questions.
I've tried to create a save method in my model where I: use a queryset to get 3 questions, save the Quiz instance (to save an id), set the queryset to the Quiz and save again. Most of my searches on this topic have shown where people are using a form to save the m2m object.
Even better, is it possible to set 3 questions to a quiz object using a view? Ultimately this is where I want to get to. A user will select a LearnGoal using request.GET in a view, and this LearnGoal will restrict the questions that will be added to the Quiz.
My models.py so far:
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)
I've tried a few variations of the above code. Currently this code gives the error:
'Question' instance expected, got <Quiz: Quiz object (4)>
from the line self.questions.set(five_questions)
How can I save multiple questions to one instance of the quiz?
回答1:
In the Quiz.save
method, you can do:
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])
Note that, random ordering (order_by('?')
) is slow but whether that will affect you totally depends on the use case.
来源:https://stackoverflow.com/questions/58787050/how-to-save-multiple-manytomany-instances-to-a-django-object