如何将多个ManytoMany实例保存到Django对象? [英] How to save multiple ManytoMany instances to a Django object?

查看:36
本文介绍了如何将多个ManytoMany实例保存到Django对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有几个Question对象的Django应用.问题和测验是通过ManyToManyField关联的.我想创建测验对象,以便每个测验被随机分配3个问题.

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.

我尝试在模型中创建一个保存方法,其中:我使用查询集获取3个问题,保存测验实例(以保存ID),将查询集设置为测验并再次保存.我在该主题上进行的大多数搜索都显示出人们在哪里使用表单保存m2m对象.

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.

更好的是,是否可以使用视图向一个测验对象设置3个问题?最终,这是我想要到达的地方.用户将在视图中使用 request.GET 选择 LearnGoal ,此LearnGoal将限制将添加到测验中的问题.

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.

到目前为止,我的models.py:

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)

我已经尝试了上述代码的一些变体.当前,此代码给出错误:'Question'实例应从 self.questions.set(five_questions)

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?

推荐答案

Quiz.save 方法中,您可以执行以下操作:

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])

请注意,随机排序( order_by('?'))速度较慢,但​​是这是否会完全影响您取决于使用情况.

Note that, random ordering (order_by('?')) is slow but whether that will affect you totally depends on the use case.

这篇关于如何将多个ManytoMany实例保存到Django对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆