【问题标题】:Python sorted function on django-queryset objectsdjango-queryset 对象上的 Python 排序函数
【发布时间】:2021-02-28 21:05:29
【问题描述】:

我首先尝试按 created_on 降序排序,然后使用相同的 product_users 查询集并在字段为名称的 foreign_key 用户对象上应用排序函数。

product_users = ProductUser.objects.filter(entity=entity).order_by('-created_on')
product_users = sorted(product_users, key=lambda pu(pu.user.name.lower(), pu.status))

我想通过在第二列 pu.status 上降序来应用订单

【问题讨论】:

  • django 中的用户模型没有“名称”字段。请改用“user.first_name”或“user.last_name”。
  • @SeyyedSajjadSanikhani 已经覆盖了 User 模型并创建了一个 User 模型字段,该字段将 name 作为 first_name 和 last_name 的组合
  • 所以试试这个排序的键值:key=lambda x: x.user.name
  • @SeyyedSajjadSanikhani 如何按具有相同排序功能的多列进行排序,如您所见,我现在想按状态列降序排序。

标签: python-3.x django django-queryset


【解决方案1】:

为了按多个属性排序,你应该让 lambda 函数返回一个属性元组而不是一个。所以你可以试试:

sorted(product_users, key=lambda pu: (pu.user.name.lower(), pu.status)

但是,如果您想按前一个属性升序排序并按后一个属性降序排序,您可以使用如下所述的函数

Python Sort Function Documentation:


def multisort(xs, specs):
    for key, reverse in reversed(specs):
        xs.sort(key=attrgetter(key), reverse=reverse)
    return xs

所以 xs 是我们要排序的列表,而 specs 是一个列表,其中包含元组作为属性的每个元组:('attr_name', reverse)

【讨论】:

  • 如何实现相同的 def multisort(xs, specs):在我的场景中,这个函数看起来很混乱。
  • 我想出了这种可行的方法:product_users = sorted(product_users, key=lambda pu: (pu.user.name.lower(), sorted(pu.status, reverse=True) ))
  • 好的,请告诉我什么是实现我需要的正确方法。提前致谢。
  • 我认为使用内联排序非常复杂,或者可能是不可能的。我认为绝对有效的唯一方法是使用 2 个排序函数。第一个按状态降序排列,第二个按 .user.name.lower() 升序排列。
  • 是的,我正在使用两个排序函数,第一个排序按名称排序,第二个按状态降序排序。
【解决方案2】:

Django 1.8+,可以注释小写用户名到查询集,然后使用order_by进行排序

from django.db.models.functions import Lower
       
product_users  = product_users.annotate(name_lower=Lower('user__name'))
product_users  = product_users.order_by('name_lower', '-status')

编辑: 如果你真的因为某种原因需要使用 sorted 函数,请尝试这个link中的答案

【讨论】:

  • 我想出了这种可行的方法:product_users = sorted(product_users, key=lambda pu: (pu.user.name.lower(), sorted(pu.status, reverse=True) ))
  • 在 Django 中正确的做法是先注解,然后使用 order_by。使用 sorted 进行这种排序很复杂。
【解决方案3】:

通过同时使用两个排序函数来解决它,首先按状态降序排序,然后按用户名升序排序。

product_users = sorted(product_users, key=lambda pu: (sorted(pu.status, reverse=True), pu.user.name.lower()))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-31
    • 1970-01-01
    • 1970-01-01
    • 2020-06-20
    • 1970-01-01
    相关资源
    最近更新 更多