выпадающее меню django-filter

Я пытаюсь превратить свои поля django-filter в раскрывающиеся списки.

class UserFilter(django_filters.FilterSet):
    class Meta:
        model = Product
        fields = ['category', 'genre', 'instrument', ]


def filter(request):
    filter = UserFilter(request.GET, queryset=Product.objects.all())
    return render(request, 'filter.html', {'filter': filter})

Я пытаюсь добиться этого с помощью ModelChoiceFilter, например:

category=django_filters.ModelChoiceFilter(queryset=Product.objects.all())
genre = django_filters.ModelChoiceFilter(queryset=Product.objects.all())
instrument=django_filters.ModelChoiceFilter(queryset=Product.objects.all))) 

Оно работает! Однако вместо того, чтобы возвращать столбец желания, он возвращает title во всех полях формы django. Это исходит от моей модели.

def __str__(self):
    return self.title

Такое же поведение можно наблюдать при работе с простыми формами модели Django. В этом случае я просто переопределяю функцию label_from_instance класса ModelChoiceField следующим образом:

class CategoryModelChoiceField(ModelChoiceField):
    def label_from_instance(self, obj):
        return obj.category

Мой вопрос: как переопределить ModelChoiceFilter? Или, возможно, есть другой удобный способ добиться выпадающих списков с помощью django-filter?

ОБНОВЛЕНИЕ

Поскольку djnago-filter поставляется с выпадающими списками для ForeignKeys по умолчанию, я просто изменил свою модель. Теперь это выглядит так:

class Category(models.Model):
    category = models.CharField(max_length=50, blank=True)

class Genre(models.Model):
    genre = models.CharField(max_length=50, blank=True)


class Instrument(models.Model):
    instrument = models.CharField(max_length=50, blank=True)


class Product(models.Model):
    category = models.ForeignKey(Category)
    genre = models.ForeignKey(Genre)
    instrument = models.ForeignKey(Instrument)
    title = models.TextField(max_length=200, blank=True)

    def __str__(self):
        return self.title

Теперь он изменил свое поведение. Теперь это количество объектов, но не фактические строки. Как это:

Category object - Genre object - Instrument object - title1
Category object - Genre object - Instrument object - title2
Category object - Genre object - Instrument object - title3

Сами выпадающие списки работают нормально без какого-либо вмешательства:

class UserFilter(django_filters.FilterSet):
    class Meta:
        model = Product
        fields = ['category', 'genre', 'instrument', ]

person sretko    schedule 08.02.2017    source источник


Ответы (2)


Я наконец заставил это работать. Это рабочая модель:

class Category(models.Model):
    category = models.CharField(max_length=50, blank=True)

    def __str__(self):
        return self.category


class Genre(models.Model):
    genre = models.CharField(max_length=50, blank=True)

    def __str__(self):
        return self.genre


class Instrument(models.Model):
    instrument = models.CharField(max_length=50, blank=True)

    def __str__(self):
        return self.instrument


class Product(models.Model):
    category = models.ForeignKey(Category)
    genre = models.ForeignKey(Genre)
    instrument = models.ForeignKey(Instrument)
    title = models.TextField(max_length=200, blank=True)

    def __str__(self):
        return self.title
person sretko    schedule 08.02.2017

Я использовал то же решение, но иногда я хочу избежать полной нормализации модели. Возможно, я пропустил это, но я удивлен, что django_filters.modelChoiceFilter не просто возвращает какой-либо атрибут в наборе запросов, а не только имена внешних ключей.

Вот еще одно решение, которое динамически генерирует выбор из набора запросов.

class DynamicChoiceMixin(object):

    @property
    def field(self):
        queryset = self.parent.queryset
        field = super(DynamicChoiceMixin, self).field

        choices = list()
        have = list()
        # iterate through the queryset and pull out the values for the field name
        for item in queryset:
            name = getattr(item, self.field_name)
            if name in have:
                continue
            have.append(name)
            choices.append((name, name))
        field.choices.choices = choices
        return field


class DynamicChoiceFilter(DynamicChoiceMixin, django_filters.ChoiceFilter):
    pass


class UserFilter(django_filters.FilterSet):

    category = DynamicChoiceFilter(name=‘category’)
    genre = DynamicChoiceFilter(name=‘genre’)
    instrument = DynamicChoiceFilter(name=‘instrument’)

    class Meta:
        model = Product
        fields = ['category', 'genre', 'instrument', ]
person jsutherl    schedule 01.03.2018