我有一个Django模型:
class Field:
choice = models.CharField(choices=choices)
value = models.CharField(max_length=255)
在我的数据库中,有些情况下有3个“字段”具有相同的选择,有些情况下则有1个该选择的字段
我如何排序查询集,使其返回,按选择排序,但所有开头都以3为一组?
例如
[1,1,1,3,3,3,4,4,4,2,5]
在哪里1,2,3,4,5
可以选择?
这是我使用Django ORM可以做的最好的事情。基本上,就像在SQL中一样,您必须构造一个自定义的order_by语句。在我们的例子中,我们将其放置在SELECT中,然后按其排序:
1)获取按频率排序的选择列表: [1, 3, 4, 2, 5]
freq_list = (
Field.objects.values_list('choice', flat=True)
.annotate(c=Count('id')).order_by('-c', 'choice')
)
2)添加带有枚举的索引: [(0,1), (1,3), (2,4), (3,2), (4,5)]
enum_list = list(enumerate(freq_list))
3)创建案例列表: ['CASE', 'WHEN choice=1 THEN 0', ..., 'END']
case_list = ['CASE']
case_list += ["WHEN choice={1} THEN {0}".format(*tup) for tup in enum_list]
case_list += ['END']
4)将案例列表合并为一个字符串: 'CASE WHEN choice=1 THEN 0 ...'
case_statement = ' '.join(case_list)
5)最后,使用case语句选择一个额外的字段“ o”,该字段将是对应的顺序,然后只需按此字段进行排序
Field.objects.extra(select={'o': case_statement}).order_by('o')
为了简化所有步骤,您可以将以上代码放入Model Manager
:
class FieldManager(models.Manager):
def get_query_set(self):
freq_list = (
Field.objects.values_list('choice', flat=True)
.annotate(c=Count('id')).order_by('-c', 'choice')
)
enum_list = list(enumerate(freq_list))
case_list = ['CASE']
case_list += ["WHEN choice={1} THEN {0}".format(*tup) for tup in enum_list]
case_list += ['END']
case_statement = ' '.join(case_list)
ordered = Field.objects.extra(select={'o': case_statement}).order_by('o')
return ordered
class Field(models.Model):
...
freq_sorted = FieldManager()
现在您可以查询:
Field.freq_sorted.all()
这将使您Field
QuerySet
按频率排序choices
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句