如何在Django中以特定顺序构建查询集

我正在尝试列出用户的个人资料。我想以这样一种方式列出他们:首先要列出具有相同用户城市的个人资料,其次是州,然后是国家,最后是其他个人资料。这就是我尝试过的。 模型

class Profile(models.Model):
    uuid = UUIDField(auto=True)
    user = models.OneToOneField(User)
    country = models.ForeignKey(Country,null=True)
    state = models.ForeignKey(State,null=True)
    city = models.ForeignKey(City,null=True)

views.py     current_user = Profile.objects.filter(user = request.user)

profiles_city = Profile.objects.filter(city=current_user.city)
profiles_state = Profile.objects.filter(state=current_user.state)
profiles_country = Profile.objects.filter(country=current_user.country)
profiles_all = Profile.objects.all()
profiles = (profiles_city | profiles_state | profiles_country | profiles_all).distinct()

但是产生的结果与Profile.objects.all()

请帮助我。预先感谢

mengjie0155 回答:如何在Django中以特定顺序构建查询集

您需要QuerySet的{​​{3}}方法,该方法根据传递的参数对对象进行排序;这是在数据库上完成的:

Profile.objects.order_by(
    'current_user__city','current_user__state','current_user__country',)

编辑:

如果要按登录用户的citystatecountry的名称进行排序,则可以在Python级别使用sorted进行此操作,和自定义key可调用:

from functools import partial


def get_sort_order(profile,logged_in_profile):
    # This is a simple example,you need to filter against
    # the city-state-country combo to match precisely. For
    # example,multiple countries can have the same city/
    # state name.

    if logged_in_profile.city == profile.city: 
        return 1 
    if logged_in_profile.state == profile.state: 
        return 2 
    if logged_in_profile.country == profile.country: 
        return 3
    return 4 

logged_in_profile = request.user.profile  # logged-in user's profile
get_sort_order_partial = partial(get_sort_order,logged_in_profile=logged_in_profile)

sorted(
    Profile.objects.all(),key=get_sort_order_partial,)

在数据库级别执行相同的操作,使用CaseWhen来使Python if-elif-else类似构造:

from django.db.models import Case,When,IntegerField

Profile.objects.order_by( 
    Case( 
        When(city=logged_in_profile.city,then=1),When(state=logged_in_profile.state,then=2),When(country=logged_in_profile.country,then=3),default=4,output_field=IntegerField(),) 
)         

这将导致查询集,并且还具有更快的优势,因为所有操作都将在数据库(SELECT CASE WHEN ...)上完成。

本文链接:https://www.f2er.com/3166484.html

大家都在问