Django ORM 当通过model.Manager::values()指定“记录唯一性“判据-字段后,附加一个order_by(空)清除默认排序的“记录唯一性“判据-字段

 

Interaction with default ordering or order_by()

默认排序与order_by()之间的相互影响

Manager::values()指定字段进行合并该字段重复的记录,影响之后的集合操作(Max()、Min()、Avg())使只对相对该字段是惟一的记录进行集合操作,相对该字段不唯一的一些记录将组合成一个组作为整体参与集合操作。

这里默认排序与order_by()显式指定字段排序将影响通过values()指定的”记录惟一性”判断依据,从而需要在显式指定values(“”)的字段后要增加order_by(空)来清除默认排序的”惟一性”判据-字段,排除其对记录分组的影响。

Fields that are mentioned in the order_by() part of a queryset (or which are used in the default ordering on a model) are used when selecting the output data, even if they are not otherwise specified in the values() call. These extra fields are used to group “like” results together and they can make otherwise identical result rows appear to be separate. This shows up, particularly, when counting things.

在查询集的order_by()部分提及的字段或用于模型的默认排序的字段在选择输出数据时会被使用即使它们没在显式指明用于合并重复项的字段的values()调用中另外指定这些额外的字段用于将相像的结果分组到一起否则它们会使一致的结果行看起来表现得是分开的特别是在集合计数时会显示出来

 

By way of example, suppose you have a model like this:

#~~~~~~~~~

from django.db import models

 

class Item(models.Model):

    name = models.CharField(max_length=10)

    data = models.IntegerField()

 

    class Meta:

        ordering = ["name"]

#~~~~~~~~~

The important part here is the default ordering on the name field. If you want to count how many times each distinct data value appears, you might try this:

这里重要的部分是name字段上的默认排序。如果你想要每个惟一的data值出现了多少次,你可能尝试这个:

#~~~~~~~

# Warning: not quite correct! 警告:不是很对!

Item.objects.values("data").annotate( Count("id") )

#你明明显式指定(values(“data”))来分组,设想注释的Cound(“id”)应该按”data”字段分出的组中统计

#~~~~~~~

…which will group the Item objects by their common data values and then count the number of id values in each group. Except that it won’t quite work. The default ordering by name will also play a part in the grouping, so this query will group by distinct (data, name) pairs, which isn’t what you want. Instead, you should construct this queryset:

。。。这将通过Item对象们的公用的data值来分组Item对象们,然后在每个分组合计和’id’值的数量。除此之外,它不能正常工作。name字段的默认排序也会影响分组因此这个查询将会通过惟一的(data,name)对来分组,这不是你想要的。反而,你应该构造这个查询集:

#~~~~~~

Item.objects.values("data").annotate( Count("id") ).order_by()

#~~~~~~

…clearing any ordering in the query. You could also order by, say, data without any harmful effects, since that is already playing a role in the query.

。。。这清除查询中的任何排序(order_by()的实参为空。你也可以根据,比如说,data来排序,并且没有任何有害效果,因为’data’已经在查询的排序中起作用了。

This behavior is the same as that noted in the queryset documentation for distinct() and the general rule is the same: normally you won’t want extra columns playing a part in the result, so clear out the ordering, or at least make sure it’s restricted only to those fields you also select in a values() call.

这个与查询集文档介绍的distinct()在行为上是一样的大体上的规则是一样的通常当你不希望额外的列参与到结果中那就清除排序ordering(因为默认排序依据的字段肯定也会被SELECT,被SELECT考察的字段才能参与排序这自然也会出现在结果中从而不是单纯只根据你显式指定的values(“”)字段进行排序),或至少确定默认排序只约束那些也在你的values()调用中选择了的字段

Note

 

You might reasonably ask why Django doesn’t remove the extraneous columns for you. The main reason is consistency with distinct() and other places: Django never removes ordering constraints that you have specified (and we can’t change those other methods’ behavior, as that would violate our API stability policy).

    你可能合理地疑惑为什么Django不为你移除额外的列(就像上面当我执行Item.objects.values("data").annotate( Count("id") )时本意是只按”data”合并重复项进行Coutn集合,为什么Django不在后台帮我处理成Item.objects.values("data").annotate( Count("id") ).order_by(),自动帮我清除默认排序中使用的不在我显式的values(“data”)中指定的排序字段?)主要的原因是distinct()与其他地方的一致性:Django从不移除你已经指定了的排序约束(并且Django也不能改变那些其他方法的行为,因为那将违反Django的API稳定性政策)。

 

 

猜你喜欢

转载自blog.csdn.net/HayPinF/article/details/108697374