Django-filter: Поднимите исключение, если поля не указаны в FilterSet

Созданный на 28 сент. 2016  ·  11Комментарии  ·  Источник: carltongibson/django-filter

class BooksFilter(filters.FilterSet):
    class Meta:
        model = Books

При пропуске параметра fields в классе набора фильтров (как указано выше) все поля модели будут включены в набор фильтров. Это может привести к утечке информации при использовании вместе с DRF, когда форма отображается в доступном для просмотра API.

И Django, и DRF требуют явного указания полей в формах/сериализаторах из-за потенциальных проблем с безопасностью. Это также должно быть необходимо в наборах фильтров django-filter.
http://www.django-rest-framework.org/api-guide/serializers/#specifying-what-fields-to-include
https://docs.djangoproject.com/en/1.10/topics/forms/modelforms/#выбор полей для использования

Я буду рад помочь с PR или объяснить, в каких ситуациях это может привести к утечке информации, если это необходимо.

ImprovemenFeature

Самый полезный комментарий

Кстати, утечка данных была частично устранена в #451. Прямо сейчас вы должны увидеть предупреждения об устаревании о неопределенном/изменяющемся поведении. В 1.0 новое поведение заключается в том, что отсутствие Meta.fields или Meta.fields = None ничего не делает.

Все 11 Комментарий

@ nip3o Ага. Рад видеть это.

Я также хотел бы, чтобы поля требовали объявленных фильтров в соответствии с DRF, пока вы этим занимаетесь... 😉

Кстати, утечка данных была частично устранена в #451. Прямо сейчас вы должны увидеть предупреждения об устаревании о неопределенном/изменяющемся поведении. В 1.0 новое поведение заключается в том, что отсутствие Meta.fields или Meta.fields = None ничего не делает.

Я также хотел бы, чтобы поля требовали объявленных фильтров в соответствии с DRF, пока вы это делаете.

Я не уверен, как это будет работать с синтаксисом dict для Meta.fields . например:

class UserFilter(filters.FilterSet):
    username = filters.CharFilter()

    class Meta:
        model = User
        fields = {
            'name': ['contains', 'startswith', 'endswith', ...'],
            ???
        }

Я не уверен, как это будет работать с синтаксисом dict

Конечно.

Я все еще вроде :-1: на этом. Я не вижу способа разрешить синтаксис Meta.fields dict с объявленными фильтрами. По крайней мере, не так, чтобы это было неловко:

class UserFilter(filters.FilterSet):
    username = filters.CharFilter(name='username', lookup_expr='exact')
    username_like = filters.CharFilter(name='username', lookup_expr='icontains')
    relevance = filters.CharFilter(method='filter_relevance')

    class Meta:
        model = User
        fields = {
            'name': ['contains', 'startswith', 'endswith', ...'],
            'username': ['exact'],  # match w/ the lookup_expr? 
            'username_like': ['icontains'],
            'relevance': [???]  # What about method filters?
        }

Кроме того, это требование приводит к проблемам с пользовательскими полями модели, которые не наследуют класс поля из FilterSet.FILTER_DEFAULTS . Для настраиваемых полей потребуется следующее:

class NetworkSettingFilter(FilterSet):
    mask = MaskFilter(...)

    class Meta:
        model = NetworkSetting
        fields = ['mask']
        filter_overrides = {
            SubnetMaskField: {'filter_class': MaskFilter},
        }

# vs.

class NetworkSettingFilter(FilterSet):
    mask = MaskFilter(...)

    class Meta:
        model = NetworkSetting

Примечание: этот более поздний момент мы _могли_ исправить. Нам пришлось бы переписать автогенерацию, чтобы она вел себя как сериализаторы DRF, а не как формы модели Django. В любом случае, меня больше всего беспокоит синтаксический конфликт.

OK. Оставим это пока.

Мне нравится оригинальное предложение. Я склоняюсь к тому, чтобы ограничиться _If fields is a list..._ Но мне нужно подумать об этом немного подробнее.

Немного назад и вперед, но я собираюсь пересмотреть это только для оригинального выпуска .

Должен быть объявлен либо fields , либо exclude . fields = '__all__' должно быть минимумом.

(Мы можем вернуться к тому, чтобы не обеспечивать совпадение списков.)

Соответствующий код DRF находится здесь :

        assert not (fields is None and exclude is None), (
            "Creating a ModelSerializer without either the 'fields' attribute "
            "or the 'exclude' attribute has been deprecated since 3.3.0, "
            "and is now disallowed. Add an explicit fields = '__all__' to the "
            "{serializer_class} serializer.".format(
                serializer_class=self.__class__.__name__
            ),
        )

Нам нужно подобное дополнение в filters_for_model :

    # Setting exclude with no fields implies all other fields.
    if exclude is not None and fields is None:
        fields = ALL_FIELDS

Для начала нужно отказаться от него.

Должен быть объявлен либо fields , либо exclude . fields = '__all__' должно быть минимумом.

Я определенно могу отстать от этого. Сейчас работаю над пиаром.

Прохладный.

Думая о, не беспокойтесь об амортизации. Это небольшое изменение, связанное с основным изменением версии. Просто не забудьте указать это в примечаниях к изменениям. 👍🏽

Думая о, не беспокойтесь об амортизации. Это небольшое изменение, связанное с основным изменением версии. Просто не забудьте указать это в примечаниях к изменениям.

Намерение немного отличается, но мы на самом деле рассмотрели это здесь .

Кроме того, в настоящее время выполняется рефакторинг filters_for_model , чтобы не пытаться создавать фильтры для объявленных фильтров. (Это относится к примеру с подсетью/маской, где fields = ['mask'] вызовет ненужное исключение.

Закрыто № 550

Была ли эта страница полезной?
0 / 5 - 0 рейтинги