django values_list意外行为

时间:2016-06-08 17:34:36

标签: mysql django django-models django-queryset

我有一个有2个字段的模型

class MyModel: 
    name = charField()
    code = charField(unique=True)

多数民众赞成。没有其他领域或元类,没有......它都在这里。

在Mysql表中我有8个条目/行

ID name              code
-------------------------
8  Aborted           ABT
7  Returned          RTC
6  Delivery-Failed   DLF
5  Delivered         DLV
4  Out-for-Delivery  OFD
3  Ready-to-Deliver  RTD
2  Order-Placed      OPD
1  in transit        INT

那就是说,我做的第一个条目是("在传输中#34;," INT")然后是OPD ......依此类推。

所以当我在这个表上使用values_list时,它会返回

MyModel.objects.values_list('code', 'name')

[(u'INT', u'in transit'), (u'OPD', u'Order-Placed'), (u'RTD', u'Ready-to-Deliver'), (u'OFD', u'Out-for-Delivery'), (u'DLV', u'Delivered'), (u'DLF', u'Delivery-Failed'), (u'RTC', u'Returned'), (u'ABT', u'Aborted')]

这是预期的顺序,我的意思是第一个第一个和最后一个。

现在我做MyModel.objects.values_list('code') 它返回

[(u'ABT',), (u'DLF',), (u'DLV',), (u'INT',), (u'OFD',), (u'OPD',), (u'RTC',), (u'RTD',)]

State.objects.values_list('code', flat=True)也会返回相同的结果。

起初似乎是随机的,但似乎按字母排序。

这不是全部, 我甚至试图在过滤器中传递切片列表

MyMode.objects.filter(code__in=['DLF', 'RTC', 'ABT'][1:]).values_list('code', 'name')

并再次返回一些无序数据 [(u'ABT', u'Aborted'), (u'RTC', u'Returned')]

现在我想了解为什么会这样。如果它在代码中,为什么django开发人员默认进行这种排序?

PS:我没有找到任何有用的文件 https://docs.djangoproject.com/en/1.9/ref/models/querysets/#values-list

代码也没有说什么 https://github.com/django/django/blob/master/django/db/models/query.py#L146

PS:我使用的是django 1.9.6和Mysql Ver 14.14 Distrib 5.5.47

1 个答案:

答案 0 :(得分:1)

最可能的原因是数据库返回的默认顺序。我不能比我更确定,因为我不知道是否已发布完整的模型描述。据我所知,这里没有DJANGO魔术。为了保证预期的排序,Django依赖于模型作者指定的default ordering

这似乎是当前的most relevant/related SO QA。请查看OP的编辑和接受的答案。

修改 好的,它显示为mysql's default order does depend on either insert order or primary key。数据库可以自由地实现自己的默认顺序,这是一件好事,因为他们可以选择为这些情况提供最佳性能。这正是DJANGO模型和其他ORM专门为模型提供默认排序的原因。

再次,重复(这不能足够迭代!) - 引自an answer in this post

  

在SQL世界中,顺序不是一组数据的固有属性。   因此,您的RDBMS无法保证您的数据会来   除非你,否则按照一定的顺序 - 或者甚至以一致的顺序 - 返回   使用ORDER BY子句查询数据

如果未指定顺序,请特别注意在查询集之上使用切片,因为SQL TOP应用于有序结果,并且没有明确的排序顺序RDBMS实现可以自由选择他们自己的,可能在版本或even execution to execution中随机使用一个(因为它取决于所讨论的RDBMS的查询计划实现)。