Django-filter: Поля фильтра технически разрешены для всех действий представления DRF. Это нарушает схему CoreAPI.

Созданный на 16 мая 2018  ·  3Комментарии  ·  Источник: carltongibson/django-filter

При использовании CoreAPI с включенным DRF и DjangoFilterBackend клиент также пытается сопоставить все поля для действий создания, обновления или частичного_обновления с параметрами запроса. Это лишает клиента возможности использовать эти методы.

Пример

Если у нас есть запрос, который пытается создать книгу с именем, а имя также является фильтруемым полем в нашей модели:

# book views
class BookViewSet():
    filter_fields = ('name',)
   # ...
// schema
client.action('book', 'create', { 'name': 'My Awesome Book' });

Это создаст запрос как с именем в параметре URL, так и с телом запроса. Это не ожидаемое поведение.

POST /api/book?name=My%20Awesome%20Book

name=My Awesome Book

Предложенное решение

Мы исправили это в нашем коде, указав вместо этого серверную часть фильтра DRF на пользовательское переопределение с помощью следующего кода:

class OnlyFilterOnReadDjangoFilterBackend(DjangoFilterBackend):
    """ A filter backend that only allows for filtering by properties on
    actions deemed as safe. This means that create, update, and partial_update
    actions will not provide filter options.
    """
    SAFE_ACTIONS = ('list', 'retrieve')

    def get_schema_fields(self, view):
        if view.action in self.SAFE_ACTIONS:
            return super().get_schema_fields(view)
        return []

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

Привет @Sonictherocketman. Спасибо за отчет.

Моя первая мысль заключается в том, что это ошибка клиентского API — он неправильно различает параметры строки запроса и тело запроса при построении запроса.

В общем, просто отключать фильтрацию для небезопасных действий неправильно. Фильтрация происходит при установлении базового набора запросов, для которого будет производиться обновление.

Я пока оставлю это открытым, просто чтобы подумать об этом.

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

Привет @Sonictherocketman. Спасибо за отчет.

Моя первая мысль заключается в том, что это ошибка клиентского API — он неправильно различает параметры строки запроса и тело запроса при построении запроса.

В общем, просто отключать фильтрацию для небезопасных действий неправильно. Фильтрация происходит при установлении базового набора запросов, для которого будет производиться обновление.

Я пока оставлю это открытым, просто чтобы подумать об этом.

Я также думаю, что это проблема клиента, но чем больше я думал об этом, тем больше я чувствовал, что действия на самом деле не имеют никакого смысла в запросах на запись (особенно запись на определенный ресурс), и imo схема не должна иметь эти поля, если они не должны использоваться.

Спасибо за быстрый ответ, и мне очень интересно, что вы думаете по этому поводу.

Более или менее, я думаю, что здесь мы ограничены нашим желанием _automagic_ генерировать код, опережая технологию (в ее текущем состоянии).

Мы не можем (пока) сделать со схемами (в любом из доступных форматов) многое, что хотелось бы — например, с CoreAPI мы пока не можем группировать параметры вместе, чтобы фильтр диапазона дат отображал что они родственники. (Мы можем написать намного больше схем вручную, но, конечно, никто не хочет этого делать.)

Но он развивается, и вместе с ним развиваются и инструменты. Это улучшится.

Что эта конкретная строка:

client.action('book', 'create', { 'name': 'My Awesome Book' });

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

В настоящее время это не то, что мы можем здесь решить. Тем не менее, еще раз спасибо за отчет.

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