所以我有3个模特
class User(models.Model):
class UserQuestions(models.Model):
user = models.ForeignKey(User)
question = models.ForeignKey(Question)
class UserAnswers(models.Model):
user = models.ForeignKey(User)
question = models.ForeignKey(Question)
我想获得所有用户的列表,但我想过滤他们的userquestion_set并使用问题字段使用transwer_set,然后使用countquestions_set和useranswer_set之和的计数来注释查询集。
如果我这样做:
User.objects.filter(Q(userquestions__question_field=value)&Q(useranswers__question_field=value)).annotate
它过滤我的用户,我想过滤他们的用户问题集和useranswers,以便它们只包含那个字段与我的值相等的问题,以便为查询集中的行获得正确的注释。
非常感谢任何帮助。
答案 0 :(得分:0)
你走在正确的轨道上。
将对您的查询进行评估的结果行类似于:
id | userquestion__id | userquestion__user_id | userquestion__value | usweranswer__id | useranswer__user_id | useranswer__value
适用于User
,UserQuest
和UserAnswer
的所有组合,其中*__user_id
等于id
。因此,当您将&
个Q
个对象放在一起时,您只会考虑与Q
个对象匹配的行。这就是为什么您的注释仅适用于同时具有符合您条件的问题和答案的用户。所有其他User
都被过滤掉了。
对|
对象使用Q
对您也没有多大帮助,因为不匹配的条件会被视为误报,反之亦然。
因此,您唯一的选择是首先加载所有用户,然后使用带有答案计数的正确答案加载所有用户,然后使用带有问题计数的正确问题加载所有用户。最后,您应该使用相关计数对用户进行注释。
编辑(示例): 以下未经过测试,我为生锈的Python道歉:
users = User.objects.all()
users_with_right_answers = defaultdict(
int,
{
user.id: user.right_answer_count for user in User.objects.filter(
useranswer__value='...').annotate(
right_answer_count=Count('useranswer')
}
)
users_with_right_questions = defaultdict(
int,
{
user.id: user.right_question_count for user in User.objects.filter(
userquestion__value='...').annotate(
right_question_count=Count('userquestion')
}
)
for user in users:
user.right_answer_count = users_with_right_answers[user.id]
user.right_question_count = users_with_right_questions[user.id]
我们的想法是,我们可以通过三个简单的查询来完成所有操作,因为只有一个查询不可能。