如何允许通过自定义list_display字段在Django管理员中进行排序,该字段没有DB字段也没有可注释的

时间:2022-09-12 09:09:28

I have a custom list_display field which is responsible for a column of integers in one of my admin pages.

我有一个自定义list_display字段,它负责我的一个管理页面中的整数列。

I need to allow staff members to sort according to it.

我需要让工作人员按照它排序。

There's a solution for how to acheive that if the integer represents a count/average/etc of some DB field, which is not the case for me.

如果整数代表某些DB字段的计数/平均值等,那么有一个解决方案可以实现,但对我来说并非如此。

[ the solution for that case is here: Django admin: how to sort by one of the custom list_display fields that has no database field ]

[该案例的解决方案在这里:Django admin:如何通过没有数据库字段的自定义list_display字段之一进行排序]

Any ideas how I can achieve this sorting without actually creating and maintaining a DB field for the values?

任何想法如何实现这种排序,而不实际创建和维护值的数据库字段?

1 个解决方案

#1


5  

The sorting is done at the DB Engine (in an order by clause), so I don't think you will be able to achieve what you want unless you materialize a field in the model. Computed states are not sortable at this point (at least not in the admin interface, if you were using your own interface you could use extra).

排序是在数据库引擎上完成的(按照order by子句),所以除非你在模型中实现了一个字段,否则我认为你无法实现你想要的。此时计算状态不可排序(至少不在管理界面中,如果您使用自己的界面,则可以使用额外的)。

If the problem were filtering, you could write a custom FilterSpec (which doesn't appear to be documented anywhere, but SO has a good example).

如果问题是过滤,你可以编写一个自定义的FilterSpec(似乎没有在任何地方记录,但SO有一个很好的例子)。

But for sorting in the admin your only option is a materialized field, I'm afraid.

但是对于在管理员中排序,你唯一的选择是物化领域,我担心。

Edit:

Hmmm...

You could try something. It is possible (albeit I don't think it is documented anywhere formally) to change the queryset used by a ModelAdmin. If your computed field is simple enough to be embedded in the query itself you could do something like:

你可以尝试一下。有可能(虽然我不认为它在任何地方正式记录)更改ModelAdmin使用的查询集。如果您的计算字段足够简单,可以嵌入查询本身,您可以执行以下操作:

class BlahAdmin(admin.ModelAdmin):
    ... Whatever definitions ...

    def queryset(self, request):
        return Blah.objects.extra(select={'computed': "count(field_x)"})

This might work. It is untested though.

这可能会奏效。虽然没经过测试。

#1


5  

The sorting is done at the DB Engine (in an order by clause), so I don't think you will be able to achieve what you want unless you materialize a field in the model. Computed states are not sortable at this point (at least not in the admin interface, if you were using your own interface you could use extra).

排序是在数据库引擎上完成的(按照order by子句),所以除非你在模型中实现了一个字段,否则我认为你无法实现你想要的。此时计算状态不可排序(至少不在管理界面中,如果您使用自己的界面,则可以使用额外的)。

If the problem were filtering, you could write a custom FilterSpec (which doesn't appear to be documented anywhere, but SO has a good example).

如果问题是过滤,你可以编写一个自定义的FilterSpec(似乎没有在任何地方记录,但SO有一个很好的例子)。

But for sorting in the admin your only option is a materialized field, I'm afraid.

但是对于在管理员中排序,你唯一的选择是物化领域,我担心。

Edit:

Hmmm...

You could try something. It is possible (albeit I don't think it is documented anywhere formally) to change the queryset used by a ModelAdmin. If your computed field is simple enough to be embedded in the query itself you could do something like:

你可以尝试一下。有可能(虽然我不认为它在任何地方正式记录)更改ModelAdmin使用的查询集。如果您的计算字段足够简单,可以嵌入查询本身,您可以执行以下操作:

class BlahAdmin(admin.ModelAdmin):
    ... Whatever definitions ...

    def queryset(self, request):
        return Blah.objects.extra(select={'computed': "count(field_x)"})

This might work. It is untested though.

这可能会奏效。虽然没经过测试。