在Django Admin中按自定义店铺名称字段对产品列表字母排序
解决方案
要实现按店铺名称(优先show_name,无值时用name)对产品排序,你可以通过**注解(annotate)**结合Case/When实现字符串字段的条件取值,再基于这个注解字段排序。具体步骤如下:
- 首先导入Django的条件表达式模块:
from django.db.models import Case, When, CharField
- 重写
ProductAdmin的get_queryset方法,添加用于排序的注解字段,同时给自定义列指定排序依据:
class ProductAdmin(admin.ModelAdmin): list_display = ["number", "name", "get_store_name",] def get_store_name(self, obj): return obj.store.show_name or obj.store.name # 关联自定义列与注解字段,支持点击列头排序 get_store_name.admin_order_field = 'store_display_name' get_store_name.short_description = "店铺名称" # 可选,设置列的友好显示名 def get_queryset(self, request): qs = super().get_queryset(request) # 注解条件字段:优先取show_name,无有效值时取name qs = qs.annotate( store_display_name=Case( When(store__show_name__isnull=False, store__show_name__exact='', then='store__name'), When(store__show_name__isnull=False, then='store__show_name'), default='store__name', output_field=CharField() ) ) # 默认按注解字段升序排序 return qs.order_by('store_display_name')
代码说明:
Case/When实现了字符串的条件取值逻辑:先判断show_name是否为空字符串或null,满足则用name,否则用show_name;annotate生成的store_display_name是数据库层面计算的字段,完全支持order_by排序;get_store_name.admin_order_field将自定义列与注解字段绑定,让admin列表的"店铺名称"列支持点击排序;- 简化了原
get_store_name的逻辑,用or更简洁(show_name为空字符串或null时,or会自动返回name)。
内容的提问来源于stack exchange,提问作者xtlc
相关产品推荐
相关产品推荐

