django condenate两个QuerySet按顺序进行



,所以我有一个带有选择字段的模型。在此选择字段中,大约有100个条目。在这些条目中,我有许多条目,例如" Colorado -Denver",我想在列表的顶部拥有这些条目,因此所有带有"组织Colorado"的条目都位于列表的顶部,以及所有内容否则按词典顺序排序。

我尝试过两个单独的查询集(这似乎是一个坏主意,但只有100个左右的条目可以管理)。似乎有很多方法可以结合这两个查询集,但没有保持顺序(这是重点)。我已经尝试过:

class CreateContactForm(ModelForm):
    ...
    def __init__(self, *args, **kwargs):
        super(CreateContactForm, self).__init__(*args, **kwargs)
        p = models.ConstantContactList.objects.filter(
            name__startswith=settings.PREF_ORGANIZATION_PREFIX
        )
        np = models.ConstantContactList.objects.filter(
            name__regex=r'^(?!{})'.format(settings.PREF_ORGANIZATION_PREFIX)
        ).order_by('-name')
        self.fields['cc_lists'].queryset = list(p) + list(np)

这不起作用,尽管可能会有某种方法可以将该列表转换回QuerySet,或者是否有办法绕过QuerySet?我不知道。谁能提供有关我该怎么办的线索?

我建议不要尝试订购QuerySet并在渲染层(模板或表单)中处理排序。这样,如果您想本地代码本地化,则不必更改查询。

假设您使用forms.Select小部件。您可能需要从这个小部件继承并覆盖render_menu逻辑,以便自己构造并自己处理订购。您将可以访问渲染或无义的选项,因此从那时起不应该是一个问题。

好。我想出了一个在这里有效的解决方案,我将其提供给有同样需要的其他人。

from django.forms.widgets import Select
import re
class CustomOrderingWidget(Select):
    def __init__(self, priority_regex, sort='+', attrs=None):
        super(CustomOrderingWidget, self).__init__(attrs)
        self.regex = re.compile(priority_regex)
        self.sort = sort
        self.template_name = 'django/forms/widgets/select.html'
    def render(self, name, value, attrs=None, renderer=None):
        context = self.get_context(name, value, attrs)
        optgroups = context.get('widget').get('optgroups')
        firsts, others = [], []
        for grp in optgroups:
            if self.regex.search(grp[1][0].get('label')):
                firsts.append(grp)
            else:
                others.append(grp)
        if self.sort == '+':
            kfn = lambda x: x[1][0].get('label')
            context['widget']['optgroups'] = sorted(firsts, key=kfn) +
                                               sorted(others, key=kfn)
        elif self.sort == '-':
            kfn = lambda x: x[1][0].get('label')
            context['widget']['optgroups'] =
                sorted(firsts, key=kfn, reverse=True) +
                sorted(others, key=kfn, reverse=True)
        else:
            context['widget']['optgroups'] = firsts + others
        return self._render(self.template_name, context, renderer)

然后,您可以将其插入这样的模态...

import settings # YOUR personal stuffz!
class CreateContactForm(ModelForm):
    ...
    class Meta:
       ...
        widgets = {
            # Just an example, make your own regex string!  
            'cc_lists': CustomOrderingWidget("^{0}".format(
                settings.PREF_ORGANIZATION_PREFIX
            ))
        }

最新更新