Django 过滤查询集中每个项目的反向关系
Django filter a reverse relationship of each item in a queryset
所以我有 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 和 useranswer_set,然后用总和的计数来注释查询集userquestions_set 和 useranswer_set.
如果我做类似的事情:
User.objects.filter(Q(userquestions__question_field=value)&Q(useranswers__question_field=value)).annotate
它过滤我的用户,我想过滤他们的一组用户问题和用户答案,以便它们仅包含该字段与我的值相等的问题,以便为查询集中的行获得正确的注释。
非常感谢任何帮助。
你走在正确的轨道上。
您的查询将被评估的结果行类似于:
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]
我们的想法是,我们可以在三个简单的查询中完成所有事情,因为不可能只在一个查询中完成。
所以我有 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 和 useranswer_set,然后用总和的计数来注释查询集userquestions_set 和 useranswer_set.
如果我做类似的事情:
User.objects.filter(Q(userquestions__question_field=value)&Q(useranswers__question_field=value)).annotate
它过滤我的用户,我想过滤他们的一组用户问题和用户答案,以便它们仅包含该字段与我的值相等的问题,以便为查询集中的行获得正确的注释。
非常感谢任何帮助。
你走在正确的轨道上。
您的查询将被评估的结果行类似于:
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]
我们的想法是,我们可以在三个简单的查询中完成所有事情,因为不可能只在一个查询中完成。