【问题标题】:Django ORM order by filtersDjango ORM 按过滤器排序
【发布时间】: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 次查询中获取具有此排序的对象到数据库(需要分页)?

【问题讨论】:

    标签: django django-models django-views django-orm django-database


    【解决方案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(我的错误代码)”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-01
    • 2021-07-11
    • 1970-01-01
    • 2011-01-31
    • 2010-11-04
    • 2011-05-19
    • 2013-11-26
    相关资源
    最近更新 更多