Запрос Django, который объединяет две модели и находит среднее значение оценок
В моей модели есть некоторые Тесты в Tests
модели,
в каждом тесте есть несколько вопросов, которые представлены в модели Question
,
и некоторые типы относятся к каждому тесту, которые находятся в модели TestTypes
,
и есть модель QuestionResult
, которая сохраняет оценки каждого теста:
Вот эти модели :
Test
:
class Test(BaseModel):
class DifficultyLevel(models.IntegerChoices):
EASY = 1
MEDIUM = 2
HARD = 3
types = models.ManyToManyField(
'TestType',
related_name='tests',
)
questions = models.ManyToManyField(
'question.Question',
related_name='tests',
blank=True,
help_text='Standard tests could have multiple questions.',
)
level = models.IntegerField(default=1, choices=DifficultyLevel.choices)
title = models.CharField(max_length=255)
def __str__(self):
return self.title
Вопрос:
class Question(BaseModel):
question_text = models.TextField()
def __str__(self):
return truncatewords(self.question_text, 7)
TestResult :
class TestResult(BaseModel):
candidate = models.ForeignKey(
'Candidate',
on_delete=models.CASCADE,
related_name='test_results',
)
test = models.ForeignKey(
'exam.Test',
on_delete=models.CASCADE,
)
test_score = models.DecimalField(default=0.00, max_digits=5, decimal_places=2)
def __str__(self):
return f'{self.candidate.user.email} - {self.test.title}'
TestType :
class TestType(BaseModel):
title = models.CharField(max_length=255)
def __str__(self):
return self.title
теперь я хочу получить оценку, которую заработал каждый тип
например, тест1 получил оценку =90 и тест1 имеет два типа : HTML и C++ .
Тест2 получил оценку = 50 и тест2 имеет два типа : HTML и Python
теперь я хочу найти оценку, которую получил тип HTML, которая должна быть (90+50)/2=70
как мне написать запрос?
Это может помочь вам, так как вам нужно несколько подзапросов в вашем коде Вот документация по подзапросам в django Subquery
test_type_scores = TestResult.objects.filter(test__types=OuterRef('pk')).annotate(
avg_score=Avg('test_score')
)
# Then, get the test types and their average scores
test_types = TestType.objects.annotate(
avg_score=Subquery(test_type_scores.values('avg_score')[:1])
).values('title', 'avg_score')
# You can then use this queryset to get the scores for each test type
test_types = list(test_types)
print(test_types)
Это даст вам набор запросов, содержащий типы тестов и их средние баллы. Затем вы можете использовать этот набор для получения оценок для каждого типа теста.
Например, если вы хотите получить оценку для типа теста HTML, вы можете сделать:
html_score = next(t['avg_score'] for t in test_types if t['title'] == 'HTML')
print(html_score) # 70.0