Django ORM 按过滤器排序

Posted

技术标签:

【中文标题】Django ORM 按过滤器排序【英文标题】:Django ORM order by filters 【发布时间】:2021-09-13 11:00:28 【问题描述】:

请帮我解决我的问题。我想先按一个过滤器排序对象,然后再按另一个过滤器排序。

如何在 1 次查询中获取具有此排序的对象到数据库(需要分页)?

这个例子展示了没有排序的查询集:

rooms = Room.objects.filter(Q(name__icontains=search) | Q(owner__username__icontains=search))

我有房间模型:

models.py

from django.db import models
from django.contrib.auth.models import User

class Room(models.Model):
    name = models.CharField(max_length=150)
    owner = models.ForeignKey(User, on_delete=models.CASCADE)

views.py(我的错误代码)

class RoomListView(ListAPIView):
    def get_queryset(self):
        search = 'test' #  for example
        rooms1 = Room.objects.filter(owner__username__icontains=search)
        rooms2 = Room.objects.filter(name__icontains=search)
        return list(rooms1) + list(rooms2)

错误的结果: search = "test"

[
  
    "id":1,
    "name":"test",
    "owner":
      "username":"user1"
    
  ,
  
    "id":2,
    "name":"room1",
    "owner":
      "username":"test"
    
  ,
  
    "id":3,
    "name":"test2",
    "owner":
      "username":"user2"
    
  
]

正确结果: search = "test"

[
  
    "id":2,
    "name":"room1",
    "owner":
      "username":"test"
    
  ,
  
    "id":1,
    "name":"test",
    "owner":
      "username":"user1"
    
  ,
  
    "id":3,
    "name":"test2",
    "owner":
      "username":"user2"
    
  
]

如何在 1 次查询中获取具有此排序的对象到数据库(需要分页)?

【问题讨论】:

【参考方案1】:

据我了解,您希望过滤和排序具有多列的行

对于single 列排序

rooms = Room.objects.filter(Q(name__icontains=search) | Q(owner__username__icontains=search)).order_by('name')

对于multi 列排序

在这里,我们可以使用owner_username 对列进行排序,并且相同的owner_username 行将使用name 进行排序

rooms = Room.objects.filter(Q(name__icontains=search) | Q(owner__username__icontains=search)).order_by('owner__username', 'name')

注意

您可以使用order_by() 对列进行排序 示例
# Sorting order will in the order of column_1, column_2, column_3
Room.objects.filter(.....).order_by('column_1', 'column_2', 'column_3)
您可以根据需要更改列的顺序

【讨论】:

感谢您的回答,但这有点不同。我需要一个列表,该列表将从一个过滤器中的对象开始,然后从第二个过滤器开始。在你的例子中,一切都是混合的:(【参考方案2】:

您可以使用order_by()对列进行排序

例子

# Sorting columns with id, name, username in dynamically 
order_by_list = []
# sort by name
order_by_list.append('name')
# And second username sort along with name
order_by_list.append('owner__username')
Room.objects.filter(.....).order_by(*order_by_list)

在这里,我们可以将appendcolumn动态命名为order_by_list

【讨论】:

感谢您的回答,但这有点不同。我不会使用“owner__username”== 搜索来获取对象,然后使用“name”== 搜索来获取对象。在我的问题中查看“views.py(我的错误代码)”。

以上是关于Django ORM 按过滤器排序的主要内容,如果未能解决你的问题,请参考以下文章

Django ORM 查询

Django ORM:按对象列表过滤

Django ORM按两个相关模型的最大列值过滤

django中的过滤顺序

Django ORM数据库查询操作

Django ORM数据库查询操作