如何在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)

视图.pycurrent_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((相同

请帮帮我。提前谢谢

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

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来具有类似Pythonif-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 ...(。

最新更新