Подтвердить что ты не робот

Как создать форму фильтра для (универсального) класса объектов в Django?

Я использую общий вид на основе класса Django 1.3 для отображения списка изображений, но я хочу добавить фильтр, который позволяет пользователю сузить отображаемые результаты.

Мой текущий подход работает, но чувствует себя довольно хакерским:

class ImageFilterForm(ModelForm):
    class Meta:
        model = Image

class ImageListView(ListView):
    model = Image

    def get_queryset(self):
        qs = Image.objects.select_related()  
        for item in self.request.GET:
            key, value = item, self.request.GET.getlist(item)
            # ... Filtering here ...
        return qs

    def get_context_data(self, **kwargs):
        context = super(ImageListView, self).get_context_data(**kwargs)
        context['filter_form'] = ImageFilterForm(self.request.GET)
        return context

Есть ли лучшее средство для добавления настраиваемой фильтрации в общий вид?

4b9b3361

Ответ 1

Я использую тот же подход, но общий, используя mixin:

class FilterMixin(object):

    def get_queryset_filters(self):
        filters = {}
        for item in self.allowed_filters:
            if item in self.request.GET:
                 filters[self.allowed_filters[item]] = self.request.GET[item]
        return filters

    def get_queryset(self):
        return super(FilterMixin, self).get_queryset()\
              .filter(**self.get_queryset_filters())


class ImageListView(FilterMixin, ListView):

    allowed_filters = {
        'name': 'name',
        'tag': 'tag__name',
    }

    # no need to override get_queryset

Это позволяет указать список принятых фильтров, и они не должны соответствовать фактическим ключевым словам .filter(). Затем вы можете расширить его для поддержки более сложной фильтрации (разделение запятой при использовании фильтра __in или __range - простой пример)

Ответ 2

Посмотрите django-filter это простое решение для фильтрации данных в поле зрения