首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >django管理员错误地将order by添加到查询中

django管理员错误地将order by添加到查询中
EN

Stack Overflow用户
提问于 2015-09-06 09:31:19
回答 2查看 1.5K关注 0票数 9

我已经注意到,感谢django调试工具栏,每个django管理列表页面,总是添加一个"ORDER BY id DESC“到我的所有查询中,即使我手动覆盖了admin.ModelAdmin的get_queryset方法(我通常这样做,因为我想在我的一些管理页面上进行自定义排序)

我想这并不是什么值得担心的事情,但它是数据库需要执行的额外排序操作,即使它没有任何意义。

有什么方法可以防止这种情况发生吗?在一些模型上(即使是这样,并不是所有的模型),如果我添加了排序元数据,那么它不会自动添加一个order by by id,但是它将按该字段添加,这也是我不想要的,因为这样做会将order by添加到代码中的所有其他查询中。

编辑:看起来罪魁祸首在django.contrib.admin.views.main的ChangeList,在函数get_ordering的第316行(django 1.7.10)

代码语言:javascript
运行
复制
 pk_name = self.lookup_opts.pk.name
    if not (set(ordering) & set(['pk', '-pk', pk_name, '-' + pk_name])):
        # The two sets do not intersect, meaning the pk isn't present. So
        # we add it.
        ordering.append('-pk')

我想知道这背后的原因是什么。

EDIT:为了提高性能,并且在没有给出order by的情况下,由于MySQL (和InnoDB)返回聚集索引order中的数据,因此我可以安全地删除附加的id。要做到这一点,非常简单,我刚刚扩展了django的ChangeList并修改了get_ordering方法。在那之后,只做了一个自定义的管理模型,它从ModelAdmin扩展并覆盖get_changelist方法来重新转换上面的类。

我希望它对任何人都有帮助:)

EN

回答 2

Stack Overflow用户

发布于 2018-03-18 22:23:56

我遇到了与这个问题完全相同的问题,由于ID排序,管理查询集的速度要慢4倍,而我已经有了唯一的排序。感谢@user1777914和他的工作,我不会每隔一次加载就超时!为了清楚起见,我在这里添加了这个答案,如果其他人也遇到了同样的问题。正如user1777914提到的扩展ChangeList:

代码语言:javascript
运行
复制
class NoPkChangeList(ChangeList):
    def get_ordering(self, request, queryset):
        """
        Returns the list of ordering fields for the change list.
        First we check the get_ordering() method in model admin, then we check
        the object's default ordering. Then, any manually-specified ordering
        from the query string overrides anything. Finally, WE REMOVE the primary
        key ordering field.
        """
        params = self.params
        ordering = list(self.model_admin.get_ordering(request) or self._get_default_ordering())
        if ORDER_VAR in params:
            # Clear ordering and used params
            ordering = []
            order_params = params[ORDER_VAR].split('.')
            for p in order_params:
                try:
                    none, pfx, idx = p.rpartition('-')
                    field_name = self.list_display[int(idx)]
                    order_field = self.get_ordering_field(field_name)
                    if not order_field:
                        continue  # No 'admin_order_field', skip it
                    # reverse order if order_field has already "-" as prefix
                    if order_field.startswith('-') and pfx == "-":
                        ordering.append(order_field[1:])
                    else:
                        ordering.append(pfx + order_field)
                except (IndexError, ValueError):
                    continue  # Invalid ordering specified, skip it.

        # Add the given query's ordering fields, if any.
        ordering.extend(queryset.query.order_by)

        # Ensure that the primary key is systematically present in the list of
        # ordering fields so we can guarantee a deterministic order across all
        # database backends.
        # pk_name = self.lookup_opts.pk.name
        # if not (set(ordering) & {'pk', '-pk', pk_name, '-' + pk_name}):
        #     # The two sets do not intersect, meaning the pk isn't present. So
        #     # we add it.
        #     ordering.append('-pk')

        return ordering

然后在你的ModelAdmin中只需覆盖get_changelist:

代码语言:javascript
运行
复制
class MyAdmin(ModelAdmin):
    def get_changelist(self, request, **kwargs):
        return NoPkChangeList
票数 4
EN

Stack Overflow用户

发布于 2019-11-12 14:39:43

因为只需要更改ChangeList._get_deterministic_ordering(),所以7Wonders的答案可以简化为以下语句:

代码语言:javascript
运行
复制
# admin.py
class MyAdmin(ModelAdmin):
    def get_changelist(self, request, **kwargs):
        """Improve changelist query speed by disabling deterministic ordering.

        Please be aware that this might disturb pagination.
        """
        from django.contrib.admin.views.main import ChangeList

        class NoDeterministicOrderChangeList(ChangeList):
            def _get_deterministic_ordering(self, ordering):
                return ordering

        return NoDeterministicOrderChangeList 
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32419190

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档