1

我正在使用 django-select2 和表单来创建下拉列表,使用 ModelSelect2Widget。

我的问题是我过滤了“名称”字段,并且多个对象可以具有相同的“名称”但不同的“值”(请参阅​​下面的模型描述)。这会导致下拉菜单中多次出现相同的名称。

我想删除这些重复项。我尝试使用 .distinct('name') 来选择查询集,但它似乎不起作用。 使用 ModelSelect2Widget 获得的结果示例

以下是我使用的代码的描述:

我有两个由外键链接的模型

models.py

class Who(models.Model):
    name = models.CharField(max_length=256)
    value = models.CharField(max_length=256)

    def __str__(self);
        return str(self.name)

class Data(models.Model):
    who = models.ForeignKey(Who)

我使用这里描述的表格:

forms.py

from django_select2.forms import ModelSelect2Widget
...

class CreateDataForm(ModelForm):
    class Meta:
        model = Data
        fields = ('who',)
        widgets = {'who': ModelSelect2Widget(
            queryset=Who.objects.all().distinct('name'),
            search_fields=['name_icontains']
        )}

有谁知道我如何删除这些重复项?

4

2 回答 2

1

我终于找到了问题的根源。

在 django_select2 ModelSelect2Mixin 中,用于过滤要在下拉菜单中显示的值的函数 filter_queryset 以“return queryset.filter(select).distinct()”结尾。这个问题是这个 .distinct() 优于查询集中的一个 (.distinct("name"))

为了解决我的问题,我不得不重写过滤器查询集函数,并删除 .distinct():

class ModelSelect2WidgetWithoutDistinct(ModelSelect2Widget):
    """In dropdown list, shows objects from queryset without the initial .distinct()."""

    def filter_queryset(self, request, term, queryset=None, **dependent_fields):
        """Same function as in select2 ModelSelect2Mixin except last line."""
        if queryset is None:
            queryset = self.get_queryset()
        search_fields = self.get_search_fields()
        select = Q()
        term = term.replace('\t', ' ')
        term = term.replace('\n', ' ')
        for t in [t for t in term.split(' ') if not t == '']:
            select &= reduce(lambda x, y: x | Q(**{y: t}), search_fields,
                                Q(**{search_fields[0]: t}))
        if dependent_fields:
            select &= Q(**dependent_fields)

        return queryset.filter(select)  # initially queryset.filter(select).distinct()

于 2019-11-18T13:55:39.120 回答
0
# You can define queryset like this

class CreateDataForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['who'].queryset = Who.objects.distinct()

    class Meta:
        model = Data
        fields = ('who',)
于 2019-11-18T11:00:41.233 回答