Запрос уникальных значений внутри django forloop

У меня есть запрос, в котором я должен избежать двойного ввода одного и того же вопроса. На самом деле, я хотел бы получить только уникальные значения, но я использую функцию distinct() django, которая не работает. У меня есть такие модели:

class QuestionTopic(models.Model):
    name = models.CharField(max_length=255)
    question_subject = models.ForeignKey(
        QuestionSubject, on_delete=models.CASCADE)
    exam_questions_num = models.IntegerField(null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.name

    class Meta:
        ordering = ('created_at',)


class Question(models.Model):
    id = models.CharField(max_length=7,
                          unique=True,
                          primary_key=True,
                          editable=False)
    question_subject = models.ForeignKey(
        QuestionSubject, on_delete=models.CASCADE)
    text = tinymce_models.HTMLField()
    mark = models.IntegerField(default=1)
    is_published = models.BooleanField(default=True)
    question_bank_id = models.CharField(max_length=255, blank=True, null=True)
    question_topic = models.ForeignKey(
        QuestionTopic, on_delete=models.CASCADE, null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

а запрос:

        subject = QuestionSubject.objects.get(id=request.POST.get('subject'))
        question_topics = QuestionTopic.objects.filter(
            question_subject=subject)            
        questions_list = []
        for topic in question_topics:
            for q in range(topic.exam_questions_num):
                question = Question.objects.filter(
                    question_subject=subject, question_topic=topic).values_list(
                    'id', flat=True).order_by('?').distinct().first()
                questions_list.append(question)

Что я хотел бы достичь, так это иметь все различные вопросы для каждой отдельной темы внутри questions_list. Чего я не могу достичь в данный момент, так как distinct используется внутри цикла.

Просто сделайте questions_list набором:

questions_list = set()

Наборы не допускают значения более одного раза.

Вы можете работать с одним запросом с помощью:

subject = QuestionSubject.objects.get(id=request.POST.get('subject'))
question_topics = QuestionTopic.objects.filter(question_subject=subject)
questions_list = [
    question
    for topic in question_topics
    for question in Question.objects.filter(
        question_subject=subject, question_topic=topic
    ).order_by('?')[: topic.exam_questions_num]
]

Это сделает O(n) запросов с n количеством тем.

Если количество вопросов не такое большое, вы можете сделать это с помощью двух запросов с:

from random import sample

subject = QuestionSubject.objects.get(id=request.POST.get('subject'))
question_topics = QuestionTopic.objects.filter(
    question_subject=subject
).prefetch_related('question_set')
questions_list = [
    question
    for topic in question_topics
    for question in sample(topic.question_set.all(), topic.exam_question_num)
]
Вернуться на верх