基于列表显示中的自定义可调用在 Django Admin 中排序
Posted
技术标签:
【中文标题】基于列表显示中的自定义可调用在 Django Admin 中排序【英文标题】:Ordering in Django Admin based on a custom callable in list display 【发布时间】:2012-10-20 05:26:12 【问题描述】:我的列表显示中有一个自定义可调用对象。我希望能够按它排序,但它不对应单个字段,所以我不能单独使用admin_order_field
。
如果它被选为字段,我希望能够改变查询集的顺序以反映这一点。但是,看起来ChangeList
视图调用get_ordering
在 通过模型管理员的get_ordering
调用运行它,然后循环遍历给定的排序字段(格式为a.b.c.etc.y.z
,其中、b、c等都是与显示列表中的一个或多个字段对应的整数。
在此示例中,我有一个订单页面,其中客户可以是公司/组织或个人。我希望能够对其进行排序,以便首先列出人员的所有订单,然后是组织,并且全部按字母顺序排列。
让我们以这个模型管理员设置为例:
class OrderAdmin(models.ModelAdmin):
list_display = ('pk', 'date_ordered', 'customer')
def customer(self, obj):
return obj.organization or "%s %s" % (obj.first_name, obj.last_name)
目前,我无法排序,因为只有当可调用对象附加了 admin_order_field
时,排序字段才可用:
def customer(self, obj):
return obj.organization or "%s %s" % (obj.first_name, obj.last_name)
customer.admin_order_field = 'customer'
问题是,理想情况下,我希望能够截取默认代码并说,“如果其中一个字段是‘客户’,则从列表中删除该字段,而是使用["organization", "last_name", "first_name"]
对其进行排序”。但据我所知,没有办法做到这一点。
我怀疑extra(select='customer':...)
会起作用,除了我使用的是django-pyodbc
,因为这是一个 SQL Server 数据库,生成的 SQL 根本不起作用并引发错误:
SELECT *
FROM (SELECT
( COALESCE(organization, firstname + ' ' + lastname) ) AS [customer],
...,
( Row_number()
OVER (
ORDER BY [customer] ASC, [orders].[date_created] DESC,
[orders].[order_id] ASC
) ) AS
[rn]
FROM [orders]) AS X
WHERE X.rn BETWEEN 1 AND 100
错误是:
列名“客户”无效。
重写 django-pyodbc,使用 .extra
不是解决方案。
所以我想知道是否还有什么可以做的,或者我是否必须放弃单独使用客户名称作为排序字段,并将其替换为单独的组织、姓氏和名字列。
【问题讨论】:
【参考方案1】:请注意,admin_order_field 是 SQL 结果集中的一个字段。因此,您需要做的是在 admin 中覆盖 get_queryset,这样您就有了一个适用于您的排序的“字段”。
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_queryset
您可能还需要 Q() 和 F() 函数。我不知道他们是否在pyodbc中工作。
现在,这个“客户”字段应该只用于排序。它可以通过 obj.customer 访问。
然后你需要一个在那个字段上排序的函数(它也可以称为“客户”)。并在其中执行您想要使用 COALESCE 执行的逻辑。
【讨论】:
是的,正如我的问题中所述,不幸的是,仅在get_queryset
中使用 .extra
将不起作用。据我所知,这个问题从来没有解决方案。我想为ModelAdmin
类创建一个包装器,它允许admin_order_field
是可迭代的,并且单个字段名称可能会起作用。以上是关于基于列表显示中的自定义可调用在 Django Admin 中排序的主要内容,如果未能解决你的问题,请参考以下文章