使用for或if循环过滤

时间:2017-08-08 20:06:35

标签: python django django-views

所以我目前正在开展一个项目,我正在尝试改进代码。

目前,我将此作为我的views.py

def home1(request):
    if request.user.is_authenticated():


        location = request.GET.get('location', request.user.profile.location)
        users = User.objects.filter(profile__location=location) 
        print users

        matchesper = Match.objects.get_matches_with_percent(request.user)
        print matchesper

        matches = [match for match in matchesper if match[0] in users][:20]

目前,用户向我提供了一个与request.user相匹配的用户列表,matchper为我提供了与所有用户匹配的百分比。然后匹配使用这两个列表返回一个用户列表,其中包含匹配百分比并与request.users location匹配

这很有效,但是一旦使用网站的用户数量增加,这将变得非常慢?例如,我可以在匹配器的末尾添加[:50],但这意味着您永远不会与具有与request.user相同位置的旧用户匹配。

我的问题是,有没有办法只为具有相同位置的用户创建匹配器匹配?我可以在matchper或for循环之前使用if语句吗?

我还没有编写这段代码,但我确实理解了它,但是当我试图改进它时,我会陷入困境,我希望我的解释和问题是有道理的。

感谢您提前提供任何帮助我非常困难!

1 个答案:

答案 0 :(得分:1)

(我假设你正在使用matchmaker project。)

在Django中,你可以chain QuerySet methods。您会注意到,您正在使用的models.py文件定义了MatchQuerySetMatchManager。您可能还注意到get_matches_with_percent仅在Manager上定义,而不是在QuerySet中定义。

这是一个问题,但不是一个不可逾越的问题。解决它的一种方法是修改我们的管理器方法实际上在哪个QuerySet。我们可以通过创建一个基本上是get_matches_with_percent副本的新方法来做到这一点,但需要进行一些额外的过滤。

class MatchManager(models.Manager):

[...]

    def get_matches_with_percent_by_location(self, user, location=None):
        if location is None:
            location = user.profile.location
        user_a = Q(user_a__profile__location=location)
        user_b = Q(user_b__profile__location=location)
        qs = self.get_queryset().filter(user_a | user_b).matches(user).order_by('-match_decimal')
        matches = []
        for match in qs:
            if match.user_a == user:
                items_wanted = [match.user_b, match.get_percent]
                matches.append(items_wanted)
            elif match.user_b == user:
                items_wanted = [match.user_a, match.get_percent]
                matches.append(items_wanted)
            else:
                pass
        return matches

注意在第10行使用重复链接!这才是魔力。

其他说明:

  • Q objects是一种执行复杂查询的方式,例如多个“OR”条件。
  • 更好的解决方案会将get_matches_with_percentget_matches_with_percent_by_location共有的元素分解出来以保持代码“DRY”,但现在这已经足够了;)
  • 请注意get_matches_with_percent返回vanilla列表而不是Django QuerySet;这是一种“终端”方法。因此,在调用filter后,您不能使用任何其他QuerySet方法(如get_matches_with_percent)。