在 Django CMS 中,当我通过 .order_by('title_set__title')

问题描述

假设我正在查看 Django CMS 项目中一组页面的更改列表,我想按标题对其进行排序。但是对于每个创建和发布的标题/语言,都会显示一个重复的树项。对于我创建的任何其他类型的排序,这不会发生并且它应该正常工作。这将为已发布的每种语言返回一个树项,我很确定也已创建。即使使用 .distinct() ,它也会为存在的每个标题/语言返回一个树项。示例如下。

如果存在许多语言标题,例如 ('en','fr','de,and 'es ' 标题)

def get_queryset(self,request):
    queryset = super(PageAdmin,self).get_queryset(request)
    queryset = queryset.order_by('title_set__title').distinct()

现在在这个例子中,如果我按其他方式订购树项目,或者 (-publication_date,publication_end_date,-publication_end_date)。对于存在多种标题/语言的页面,我只会得到一个结果,就像它应该的那样。

def get_queryset(self,self).get_queryset(request)
    queryset = queryset.order_by('publication_date').distinct()

我有根据的猜测是它与 "title_set" 有关,它在别处预取,是许多标题的集合(每种语言 1 个)而不是单个标题,在更改列表结果中选择的语言。

在这两种方法中;

def changelist_view(self,request,extra_context=None):

def get_tree(self,request):

Class BasePageAdmin(PlaceholderAdminMixin,admin.ModelAdmin):

这是预取运行的地方。这些都是包装的标准配置。我在围绕此构建自定义系统时修改了一些内容,但这部分仍然主要是包的来源。所以我想我只需要更好地了解 Django-CMS 的工作原理和/或如何使用 prefetch_related() 。我的知识还不是绝地大师级别。

pages = pages.prefetch_related(
    Prefetch(
        'title_set',to_attr  = 'filtered_translations',queryset = Title.objects.filter(language__in=get_language_list(site.pk))
    ),)

我正在运行这些主要组件;

Django==2.2.9

django-cms==3.7.1

蟒蛇 3.7.8

Windows 10

解决方法

如果有人遇到这个问题并需要解决方案,我找到了一个解决方案或至少是一个很好的解决方法。如果这不是在 Django-CMS 中按相关 Title.title 对页面列表进行排序的正确方法,那么我很想学习正确的方法。

我最终做的是按照我想要的方式对我的查询集进行排序/排序,按照页面相关标题的标题。然后我将查询集转换为页面 id 的 values_list。然后我删除了该列表中的任何重复项,然后对数据库进行另一个查询以获取新的查询集,仅检索 values_list 中的 id 并保留我拥有 values_list 的顺序。因为我正在执行另一个数据库查询以获取一组新的页面,这是我认为这不是执行此操作的正确方法的地方,但它肯定会完成工作并且您不会有重复项。如果有人有更好的方法,请分享。

from django.db.models import Case,When
def get_queryset(self,request):
    queryset = super(PageAdmin,self).get_queryset(request)

    pk_list = queryset.order_by('title_set__title').values_list('id',flat=True)

    pk_list_cleaned = []
    [pk_list_cleaned.append(x) for x in pk_list if x not in pk_list_cleaned]

    preserved_order = Case(*[When(pk=pk,then=pos) for pos,pk in enumerate(pk_list_cleaned)])
    queryset = Page.objects.filter(pk__in=pk_list_cleaned).order_by(preserved_order)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...