Проблема
В соответствии с рекомендациями в блоге Best Practices for Designing a Pragmatic RESTful API , я хотел бы добавить fields
параметр запроса в API на основе Django Rest Framework, который позволяет пользователю выбирать только подмножество полей для каждого ресурса.
пример
Сериализатор:
class IdentitySerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = models.Identity
fields = ('id', 'url', 'type', 'data')
Обычный запрос вернет все поля.
GET /identities/
[
{
"id": 1,
"url": "http://localhost:8000/api/identities/1/",
"type": 5,
"data": "John Doe"
},
...
]
Запрос с fields
параметром должен возвращать только подмножество полей:
GET /identities/?fields=id,data
[
{
"id": 1,
"data": "John Doe"
},
...
]
Запрос с недопустимыми полями должен либо игнорировать недопустимые поля, либо вызывать ошибку клиента.
Цель
Такое возможно как-то из коробки? Если нет, то как это проще всего реализовать? Есть ли сторонний пакет, который это уже делает?
источник
QUERY_PARAMS
наquery_params
, но в остальном это работает как шарм.requests
существует как членcontext
. В производственной среде этого не происходит при запуске модульных тестов, которые создают объекты вручную.Эта функция доступна из стороннего пакета .
Объявите свой сериализатор следующим образом:
Затем поля теперь можно указать (на стороне клиента) с помощью аргументов запроса:
Также возможна фильтрация исключения, например, для возврата всех полей, кроме id:
отказ от ответственности: я автор / сопровождающий.
источник
dbrgn
реализация имеет некоторые отличия: 1. не поддерживает исключение с помощьюfields!=key1,key2
. 2. также изменяет сериализаторы вне контекста запроса GET, что может нарушить и нарушит некоторые запросы PUT / POST. 3. не накапливает поля, напримерfields=key1&fields=key2
, что удобно для приложений ajax. Он также имеет нулевое тестовое покрытие, что несколько необычно для OSS.serializers.py
views.py
источник
Настройте новый класс сериализатора пагинации
Сделать динамический сериализатор
Наконец, используйте миксин домашнего мастера для ваших APIViews
Запрос
Теперь, когда вы запрашиваете ресурс, вы можете добавить параметр,
fields
чтобы отображать только указанные поля в URL-адресе./?fields=field1,field2
Здесь вы можете найти напоминание: https://gist.github.com/Kmaschta/e28cf21fb3f0b90c597a
источник
Вы можете попробовать Dynamic REST , который поддерживает динамические поля (включение, исключение), встроенные / загруженные неопубликованные объекты, фильтрацию, упорядочивание, разбиение на страницы и многое другое.
источник
Такую функциональность мы предоставили в drf_tweaks / control-over-serialized-fields .
Если вы используете наши сериализаторы, все, что вам нужно, это передать
?fields=x,y,z
параметр в запросе.источник
Для вложенных данных я использую Django Rest Framework с пакетом, рекомендованным в документации , drf-flexfields
Это позволяет вам ограничивать поля, возвращаемые как для родительских, так и для дочерних объектов. Инструкции в readme хороши, всего несколько вещей, на которые следует обратить внимание:
Похоже, что URL-адрес нуждается в / как это '/ person /? Expand = country & fields = id, name, country' вместо того, как написано в файле readme '/ person? Expand = country & fields = id, name, country'
Именование вложенного объекта и связанное с ним имя должны быть полностью согласованными, в противном случае этого не требуется.
Если у вас есть «много», например, в стране может быть много состояний, вам нужно установить «многие»: True в сериализаторе, как описано в документации.
источник
Если вам нужно что-то гибкое, например GraphQL, вы можете использовать django-restql . Он поддерживает вложенные данные (как плоские, так и повторяемые).
пример
Обычный запрос возвращает все поля.
GET /users
С
query
другой стороны, запрос с параметром возвращает только подмножество полей:GET /users/?query={id, username}
С помощью django-restql вы можете получить доступ к вложенным полям любого уровня. Например
GET /users/?query={id, username, date_joined{year}}
Для повторяемых вложенных полей, например, групп по пользователям.
GET /users/?query={id, username, groups{id, name}}
источник