【问题标题】:Can I remove ORDER BY from a Django ORM query?我可以从 Django ORM 查询中删除 ORDER BY 吗?
【发布时间】:2013-08-08 14:25:47
【问题描述】:

默认情况下,Django 似乎将ORDER BY 添加到查询中。我可以清除它吗?

from slowstagram.models import InstagramMedia
print InstagramMedia.objects.filter().query
SELECT
  `slowstagram_instagrammedia`.`id`,
  `slowstagram_instagrammedia`.`user_id`, 
  `slowstagram_instagrammedia`.`image_url`,
  `slowstagram_instagrammedia`.`video_url`,  
  `slowstagram_instagrammedia`.`created_time`,  
  `slowstagram_instagrammedia`.`caption`, 
  `slowstagram_instagrammedia`.`filter`, 
  `slowstagram_instagrammedia`.`link`, 
  `slowstagram_instagrammedia`.`attribution_id`, 
  `slowstagram_instagrammedia`.`likes_count`, 
  `slowstagram_instagrammedia`.`type`
FROM
  `slowstagram_instagrammedia`
ORDER BY
  `slowstagram_instagrammedia`.`id`
ASC

```

【问题讨论】:

    标签: django-orm


    【解决方案1】:

    其实只要做一个query.order_by()就够了。

    这是指定的in the docs,虽然有点难找。文档说:

    如果您不希望对查询应用任何排序,甚至是默认排序,请不带参数调用 order_by()。

    这里是order_by的实现,供大家参考-

    def order_by(self, *field_names):
        """
        Returns a new QuerySet instance with the ordering changed.
        """
        assert self.query.can_filter(), \
            "Cannot reorder a query once a slice has been taken."
        obj = self._clone()
        obj.query.clear_ordering(force_empty=False)
        obj.query.add_ordering(*field_names)
        return obj
    

    【讨论】:

    • 不幸的是,force_empty=False 是这里的关键 - 它不会清除模型的默认排序。
    • order_by docs 会说 如果您不希望对查询应用任何排序,甚至不希望使用默认排序,请不带参数调用 order_by()
    • @aehlke – 不带参数调用 add_ordering 清除模型的默认排序,但请检查源代码。
    【解决方案2】:

    您可以使用:clear_ordering 查询中的方法

    """Removes any ordering settings. 
    
    If 'force_empty' is True, there will be no ordering in the resulting
    query (not even the model's default).
    """
    

    例子:

    >>> from products.models import Product
    >>> products = Product.objects.filter(shortdesc='falda').order_by('id')
    >>> print products.query
    SELECT "products_product"."id", "products_product"."shortdesc"
    WHERE "products_product"."shortdesc" = falda
    ORDER BY "products_product"."id" ASC
    >>> products.query.clear_ordering()
    >>> print products.query
    SELECT "products_product"."id", "products_product"."shortdesc"
    WHERE "products_product"."shortdesc" = falda
    

    【讨论】:

    • 在 Django 1.6 中,您必须使用clear_ordering(True)clear_ordering(False),指示是否强制清除默认模型排序。
    【解决方案3】:

    尝试在查询集末尾使用.order_by('?')

    【讨论】:

    • 这将对queryset进行随机排序,这与不指定排序方法不同,会增加性能损失。
    • 我不太了解哪个是默认值。
    猜你喜欢
    • 2011-01-11
    • 2020-09-25
    • 2012-03-04
    • 2011-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多