You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django queryset如何先按title排序再按自定义尺码列表顺序排序

Django 自定义size字段排序解决方案

以下是3种不同场景下的可行实现方案:


方案1:annotate + Case/When 全数据库通用方案

无需修改现有表结构,兼容所有Django支持的数据库,是适用范围最广的实现方式:

  1. 先导入ORM内置工具
from django.db.models import Case, When, IntegerField
  1. 构造带自定义排序的查询集
order_size_list = ['S', 'M', 'L', 'XL', 'XXL']
# 为每个size值映射对应的排序优先级,列表中越靠前的size优先级数值越小
size_order_rule = Case(
    *[When(size=size_val, then=idx) for idx, size_val in enumerate(order_size_list)],
    output_field=IntegerField(),
    # 可选:存在不在列表里的size值时,默认排到最后/最前,这里999代表排到最后
    default=999
)

queryset = RawMaterial.objects.annotate(
    size_sort_priority=size_order_rule
).order_by('title', 'size_sort_priority')

方案2:PostgreSQL 专属简化方案

如果项目使用PostgreSQL作为数据库,可以直接调用内置的ARRAY_POSITION函数简化代码,不需要写多组When判断:

from django.db.models import F, Func, IntegerField

order_size_list = ['S', 'M', 'L', 'XL', 'XXL']
size_order_rule = Func(
    order_size_list,
    F('size'),
    function='ARRAY_POSITION',
    output_field=IntegerField()
)

queryset = RawMaterial.objects.annotate(
    size_sort_priority=size_order_rule
).order_by('title', 'size_sort_priority')

方案3:长期优化方案(size为固定枚举值时适用)

如果size取值是固定不会频繁变动的枚举值,建议直接调整模型字段结构,从根源上优化排序性能:

  1. 修改模型定义,把size的排序权重直接存入字段值
class RawMaterial(models.Model):
    SIZE_CHOICES = (
        (0, 'S'),
        (1, 'M'),
        (2, 'L'),
        (3, 'XL'),
        (4, 'XXL'),
    )
    # 存储数值类型的size权重,展示时用对应的字符名即可
    size = models.IntegerField(choices=SIZE_CHOICES)
    title = models.CharField(max_length=200)
    # 其余字段省略
  1. 排序时直接调用字段即可,无需额外注解
queryset = RawMaterial.objects.order_by('title', 'size')

内容的提问来源于stack exchange,提问作者Kaloyan Georgiev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 03:45:04