django admin enable sorting for calculated fields(django admin 为计算字段启用排序)
问题描述
I have the following two fields in my db table and model (Model Name: Order):
id, branch_id, product_id, cost, quantity, status, ordered_at
And I have the following code in my OrderModelAdmin:
list_display = (
'order_number',
'branch',
'product',
'cost',
'quantity',
'calculated_total',
'status',
'ordered_at',
)
def calculated_total(self, obj):
return obj.cost * obj.quantity
calculated_total.short_description = _('Total')
Now, I want to enable sorting for this field. In reality, all I need to do is to add a column in my SELECT statement:
SELECT (t.cost * t.quantity) as TOTAL
ORDER BY TOTAL
Is there a way I can append an SQL statement for sorting in Django Admin?
It isn't possible to order by the result of the calculated_total method.
However, you can set the default ordering for your model admin by overriding the get_queryset method for your model admin, and ordering by an expression that calculates the same thing.
class OrderModelAdmin(admin.ModelAdmin):
...
def get_queryset(self, request):
qs = super(OrderModelAdmin, self).get_queryset(request)
qs = qs.order_by(F('cost')*F('quantity'))
return qs
A similar approach is to annotate the queryset with the total, and then order by that field. Assuming that cost is a DecimalField and quantity is an IntegerField, you need to use ExpressionWrapper to set the output field. See the docs on Using F() with annotations for more info.
I don't think it's possible to use total directly in list_display. However, you can alter your calculated_total method to access the annotated field. We set calculated_total.admin_order_field = 'total' so that the Django admin allows you to sort on that column by clicking on it.
from django.db.models import F, ExpressionWrapper, DecimalField
class OrderModelAdmin(admin.ModelAdmin):
list_display = ['name', 'number', 'price', 'calculated_total']
def calculated_total(self, obj):
return obj.total
calculated_total.admin_order_field = 'total'
def get_queryset(self, request):
qs = super(OrderModelAdmin, self).get_queryset(request)
qs = qs.annotate(total=ExpressionWrapper(F('cost')*F('quantity'), output_field=DecimalField())).order_by('total')
return qs
这篇关于django admin 为计算字段启用排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:django admin 为计算字段启用排序
基础教程推荐
- 包装空间模型 2022-01-01
- 修改列表中的数据帧不起作用 2022-01-01
- 无法导入 Pytorch [WinError 126] 找不到指定的模块 2022-01-01
- Plotly:如何设置绘图图形的样式,使其不显示缺失日期的间隙? 2022-01-01
- 在Python中从Azure BLOB存储中读取文件 2022-01-01
- PANDA VALUE_COUNTS包含GROUP BY之前的所有值 2022-01-01
- 使用大型矩阵时禁止 Pycharm 输出中的自动换行符 2022-01-01
- PermissionError: pip 从 8.1.1 升级到 8.1.2 2022-01-01
- 求两个直方图的卷积 2022-01-01
- 在同一图形上绘制Bokeh的烛台和音量条 2022-01-01
