Как сохранить несколько экземпляров ManytoMany в объект Django? - PullRequest
1 голос
/ 10 ноября 2019

У меня есть приложение django с несколькими объектами Question. Вопрос и Викторина связаны через ManyToManyField. Я хочу создать объекты Викторины так, чтобы каждой викторине было произвольно назначено 3 вопроса.

Я пытался создать метод сохранения в моей модели, где я: использую набор запросов, чтобы получить 3 вопроса, сохранить экземпляр Quiz (для сохранения идентификатора), установить набор запросов в Quiz и снова сохранить. Большинство моих поисков по этой теме показали, что люди используют форму для сохранения объекта m2m.

Еще лучше, можно ли задать 3 вопроса для объекта викторины с помощью представления? В конечном итоге это то, куда я хочу добраться. Пользователь выберет LearnGoal , используя request.GET в представлении, и эта LearnGoal ограничит вопросы, которые будут добавлены в Викторину.

Мои модели. пока что:

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)

Как сохранить несколько вопросов в одном экземпляре теста?

1 Ответ

1 голос
/ 10 ноября 2019

В методе 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('?')) медленный, но то, повлияет ли это на вас полностью, зависит от варианта использования.

...