我正在构建类似火种的应用程序。这是一个代表从一个用户到另一个用户的评论的模型:
class Like(models.Model):
like_from = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='outcome_likes')
like_to = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='income_likes')
is_positive = models.BooleanField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f'{self.like_from} -> {self.like_to}'
现在我正在尝试过滤所有匹配项,而我所拥有的就是以下代码:
def get_queryset(self):
return CustomUser.objects.filter(income_likes__like_from=self.request.user, income_likes__is_positive=True)\
.filter(outcome_likes__like_to=self.request.user, outcome_likes__is_positive=True)
# I also tried to go from the opposite side but
# also had no idea how to get correct solution
# Here should be some code to get intersection
# of these two querysets's values lists
# positive_likes_from = self.request.user.income_likes.all().filter(is_positive=True).values('like_from')
# positive_likes_to = self.request.user.outcome_likes.all().filter(is_positive=True).values('like_to')
但此处未注释的行将返回具有任何积极结果的用户,但不能保证将其发送给当前用户。
我想获得CustomUser
模型的查询集,该查询集具有正的收入并且在另一侧当前用户喜欢的情况下获得类似的结果。
这是我的问题的解决方案,需要对数据库进行大量SQL查询:
def get_queryset(self):
positive_likes_from = self.request.user.income_likes.all().filter(is_positive=True)
positive_likes_to = self.request.user.outcome_likes.all().filter(is_positive=True)
result = []
for like in positive_likes_from:
outcome_like_with_same_user_on_another_side = positive_likes_to.filter(like_to=like.like_from).first()
if outcome_like_with_same_user_on_another_side:
result.append((like, outcome_like_with_same_user_on_another_side))
return result
答案 0 :(得分:2)
您可以使用QuerySets
函数或intersection
运算符(QuerySet是python集)来将两个&
相交,如here所述。
因此,如果您为传出的喜欢和传入的喜欢创建两个QuerySets
:
qs1 = self.request.user.income_likes.filter(is_positive=True).values_list('like_from', flat=True)
qs2 = self.request.user.outcome_likes.filter(is_positive=True).values_list('likes_to', flat=True)
您将拥有两个user_id
列表,其中交集是匹配的用户。 flat=True
需要创建两个列表,否则每个列表中的键将不同并且交集为空:
matches = CustomUser.objects.filter(id__in=qs1.intersection(qs2))
或者如果您只想要ID列表:
match_ids = qs1 & qs2
这将为您提供与request.user
匹配的所有用户。