Запрос уникальных значений внутри 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)
]