Руководство по API платформы Django REST (1): запросы
Руководство по API платформы Django REST (2): ответы
Руководство по API платформы Django REST (3): представления
Руководство по API платформы Django REST (4): общие представления
Руководство по API платформы Django REST (5): наборы представлений
Руководство по API Django REST framework (6): Маршрутизация
Руководство по API платформы Django REST (7): анализ
Универсальный вид
Главное преимущество основанных на классах представлений заключается в том, что они позволяют вам писать повторно используемое поведение. Платформа REST использует это преимущество, предоставляя большое количество предварительно созданных представлений для предоставления общих шаблонов.
Общие представления, предоставляемые инфраструктурой REST, позволяют быстро создавать представления API, которые тесно связаны с моделями баз данных.
Если общий вид не соответствует вашим потребностям, вы можете использовать обычныйAPIView
или используйте функцию миксина и базовые классы для создания повторно используемых представлений.
взять каштан
Как правило, при использовании универсального представления необходимо создать подкласс представления и установить несколько свойств класса.
from django.contrib.auth.models import User
from myapp.serializers import UserSerializer
from rest_framework import generics
from rest_framework.permissions import IsAdminUser
class UserList(generics.ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = (IsAdminUser,)
В более сложных случаях вы также можете переопределить различные методы в классе представления. Например.
class UserList(generics.ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = (IsAdminUser,)
def list(self, request):
# 注意使用`get_queryset()`而不是`self.queryset`
queryset = self.get_queryset()
serializer = UserSerializer(queryset, many=True)
return Response(serializer.data)
Для очень простых случаев вы можете использовать.as_view()
метод для передачи атрибутов класса. Например, ваш URLconf может содержать записи, подобные следующим:
url(r'^/users/', ListCreateAPIView.as_view(queryset=User.objects.all(), serializer_class=UserSerializer), name='user-list')
Установите соответствующие параметры атрибута непосредственно в URLconf, чтобы вам даже не пришлось писать класс представления.
Справочник по API
GenericAPIView
GenericAPIView
Класс наследуется от фреймворка REST.APIView
Класс, который добавляет общее поведение к стандартным представлениям списка и сведений.
Каждое встроенное конкретное универсальное представление создается путем добавленияGenericAPIView
Класс создается путем объединения одного или нескольких классов minxin друг с другом.
Атрибуты
основные настройки
Следующие свойства управляют основным поведением представления.
-
queryset
- Набор запросов, используемый для возврата объектов из этого представления. Как правило, вы должны установить это свойство или переопределитьget_queryset()
метод. Если вы переопределяете метод представления, в методе представления вы должны вызватьget_queryset()
Это важно вместо прямого доступа к этому свойству! Поскольку REST будет внутреннеqueryset
Результат кэшируется для всех последующих запросов. -
serializer_class
- Классы сериализации для проверки и десериализации ввода и сериализации вывода. Как правило, вы должны установить это свойство или переопределитьget_serializer_class()
метод. -
lookup_field
- Поля модели, используемые для поиска объектов для отдельных экземпляров модели. По умолчанию'pk'
. Обратите внимание, что при использовании API с гиперссылками, если вам нужно использовать настраиваемые значения, необходимо убедиться, что в представлении API и классе сериализации установлено поле поиска. -
lookup_url_kwarg
- Аргументы ключевого слова URL для поиска объекта. Конфигурация URL должна содержать аргументы ключевого слова, соответствующие этому значению. Если не установлено, по умолчанию используется тот жеlookup_field
такое же значение.
Что касается последних двух параметров, я прилагаю сюда исходный код объектного запроса, чтобы все поняли.
Опустите часть кода для простоты понимания
def get_object(self):
# 先获取数据集
queryset = self.filter_queryset(self.get_queryset())
# 拿到查询参数的 key
lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
# 组装成 {key:value} 的形式
filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]}
# 查询
obj = get_object_or_404(queryset, **filter_kwargs)
# 最后返回
return obj
нумерация страниц
При использовании с представлениями списка следующие свойства используются для управления разбиением на страницы.
-
pagination_class
- Класс пагинации для использования при нумерации списков. Значение по умолчанию такое же, какDEFAULT_PAGINATION_CLASS
Настройки одинаковые, т.е.rest_framework.pagination.PageNumberPagination
. настраиватьpagination_class = None
Пейджинг будет отключен для этого представления.
фильтр
-
filter_backends
- Список классов фильтров, используемых для фильтрации набора запросов. Значение по умолчанию такое же, какDEFAULT_FILTER_BACKENDS
Установите такое же значение.
метод
основной метод
get_queryset(self)
Должен быть возвращен набор запросов представления списка, который следует использовать в качестве основы для просмотра подробного представления. По умолчанию возвращаетсяqueryset
Набор запросов, указанный свойством.
Этот метод всегда следует использовать вместо прямого доступаself.queryset
, потому что REST внутриself.queryset
Результат кэшируется для всех последующих запросов.
Можно переопределить, чтобы обеспечить динамическое поведение, например возврат разных данных для разных пользовательских запросов.
Возьмите каштан:
def get_queryset(self):
user = self.request.user
return user.accounts.all()
get_object(self)
Экземпляр объекта, который должен возвращать подробный вид. Использовать по умолчаниюlookup_field
параметр для фильтрации базового набора запросов.
Можно переопределить, чтобы обеспечить более сложное поведение, например поиск объектов на основе нескольких kwargs URL.
Возьмите каштан:
def get_object(self):
queryset = self.get_queryset()
filter = {}
for field in self.multiple_lookup_fields:
filter[field] = self.kwargs[field]
obj = get_object_or_404(queryset, **filter)
self.check_object_permissions(self.request, obj)
return obj
Обратите внимание: если ваш API не содержит каких-либо разрешений на уровне объекта, вы можете исключитьself.check_object_permissions
, а просто изget_object_or_404
Найдите возвращенный объект.
filter_queryset(self, queryset)
Учитывая набор запросов, отфильтруйте с помощью фильтра, чтобы вернуть новый набор запросов.
Возьмите каштан:
def filter_queryset(self, queryset):
filter_backends = (CategoryFilter,)
if 'geo_route' in self.request.query_params:
filter_backends = (GeoRouteFilter, CategoryFilter)
elif 'geo_point' in self.request.query_params:
filter_backends = (GeoPointFilter, CategoryFilter)
for backend in list(filter_backends):
queryset = backend().filter_queryset(self.request, queryset, view=self)
return queryset
get_serializer_class(self)
Возвращает класс, используемый для сериализации. вернуть по умолчаниюserializer_class
Атрибуты.
Можно переопределить, чтобы обеспечить динамическое поведение, например использование разных сериализаторов для операций чтения и записи, или предоставить разные сериализаторы для разных типов пользователей.
Возьмите каштан:
def get_serializer_class(self):
if self.request.user.is_staff:
return FullAccountSerializer
return BasicAccountSerializer
Сохраняйте и удаляйте хуки
Следующие методы предоставляются классом примеси, чтобы легко переопределить поведение сохранения и удаления объектов.
-
perform_create(self, serializer)
- при сохранении нового экземпляра объектаCreateModelMixin
перечислить. -
perform_update(self, serializer)
- при сохранении существующего экземпляра объектаUpdateModelMixin
перечислить. -
perform_destroy(self, instance)
- При удалении экземпляра объектаDestroyModelMixin
перечислить.
Эти хуки особенно полезны для установки свойств, которые неявно присутствуют в запросе, но не являются частью данных запроса. Например, вы можете установить свойства объектов на основе запрашивающего пользователя или на основе аргументов ключевого слова URL.
def perform_create(self, serializer):
serializer.save(user=self.request.user)
Эти точки переопределения также особенно полезны для добавления поведения, которое происходит до или после сохранения объекта, например, отправка электронных писем с подтверждением или регистрация обновлений в журнале.
def perform_create(self, serializer):
queryset = SignupRequest.objects.filter(user=self.request.user)
if queryset.exists():
raise ValidationError('You have already signed up')
serializer.save(user=self.request.user)
Примечание. Эти методы заменяют устаревшую версию 2.x.pre_save
,post_save
,pre_delete
иpost_delete
методы, которых уже нет.
Другие методы
Обычно нет необходимости переопределять следующие методы, но если вы используетеGenericAPIView
Напишите пользовательские представления, вам может понадобиться вызвать их.
-
get_serializer_context(self)
- Возвращает словарь, содержащий любой дополнительный контекст, который должен быть предоставлен для сериализации. По умолчанию включает'request'
,'view'
и'format'
ключ. -
get_serializer(self, instance=None, data=None, many=False, partial=False)
- Возвращает экземпляр сериализатора. -
get_paginated_response(self, data)
- вернуть стиль пагинацииResponse
объект. -
paginate_queryset(self, queryset)
- разбивает набор запросов на страницы по мере необходимости или возвращает объект страницы, или если разбиение по страницам не настроено для этого представленияNone
. -
filter_queryset(self, queryset)
- Учитывая набор запросов, отфильтровать с помощью фильтра, возвращая новый набор запросов.
Mixins
Класс mixin используется для предоставления операций для базового поведения представления. Обратите внимание, что класс примеси предоставляет методы действия вместо прямого определения методов обработчика, таких как.get()
и.post()
. Это позволяет более гибко комбинировать поведение.
Доступ к классу миксина можно получить изrest_framework.mixins
импортировать в.
ListModelMixin
обеспечить.list(request, *args, **kwargs)
метод, реализующий вывод набора запросов.
Возвращает, если набор запросов заполнен200 OK
Ответ с сериализованным представлением набора запросов в качестве тела ответа. Данные ответа могут быть разбиты на страницы.
CreateModelMixin
поставка.create(request, *args, **kwargs)
методы, реализующие создание и сохранение новых экземпляров модели.
Если объект был создан, он вернет201 Created
Ответ с сериализованным представлением этого объекта в качестве тела ответа. Если представление содержит ключ с именем url, ответLocation
заголовок будет заполнен этим значением.
Вернется, если данные запроса, предоставленные для создания объекта, недействительны.400 Bad Request
Ответ с подробностями об ошибке в качестве тела ответа.
RetrieveModelMixin
поставка.retrieve(request, *args, **kwargs)
метод, реализующий возврат существующего экземпляра модели в ответе.
Возвращает, если объект может быть получен200 OK
Ответ с сериализованным представлением объекта в виде тела ответа. В противном случае он вернет404 Not Found
.
UpdateModelMixin
поставка.update(request, *args, **kwargs)
метод, реализующий обновление и сохранение существующих экземпляров модели. также обеспечивает.partial_update(request, *args, **kwargs)
метод, который аналогичен методу обновления, за исключением того, что все обновляемые поля являются необязательными. Это позволяет поддерживать HTTPPATCH
просить.
Возвращает, если объект был успешно обновлен200 OK
Ответ с сериализованным представлением объекта в виде тела ответа.
Вернется, если запрошенные данные, предоставленные для обновления объекта, недействительны.400 Bad Request
Ответ с подробностями об ошибке в качестве тела ответа.
DestroyModelMixin
обеспечить.destroy(request, *args, **kwargs)
метод для удаления существующего экземпляра модели.
Если объект был удален, возвращает204 No Content
, иначе он вернет404 Not Found
.
Список встроенных классов представлений
Следующие классы являются конкретными универсальными представлениями. Как правило, вы должны использовать их, если вам не нужно специальное поведение.
Доступ к этим классам представлений можно получить изrest_framework.generics
импортировать в.
CreateAPIView
Только создание экземпляра.
обеспечитьpost
Метод обработки запроса.
Унаследовано от:GenericAPIView
, CreateModelMixin
ListAPIView
Используется только для чтения списка экземпляров модели.
обеспечитьget
Метод обработки запроса.
Унаследовано от:GenericAPIView
, ListModelMixin
RetrieveAPIView
Используется только для запроса одного экземпляра модели.
обеспечитьget
Метод обработки запроса.
Унаследовано от:GenericAPIView
, RetrieveModelMixin
DestroyAPIView
Используется только для удаления одного экземпляра модели.
обеспечитьdelete
Метод обработки запроса.
Унаследовано от:GenericAPIView
, DestroyModelMixin
UpdateAPIView
Используется только для обновления одного экземпляра модели.
поставкаput
иpatch
Метод обработки запроса.
Унаследовано от:GenericAPIView
, UpdateModelMixin
ListCreateAPIView
Вы можете либо получить коллекцию экземпляров, либо создать список экземпляров.
поставкаget
иpost
Метод обработки запроса.
Унаследовано от:GenericAPIView
, ListModelMixin
,CreateModelMixin
RetrieveUpdateAPIView
Может как запрашивать, так и обновлять один экземпляр
поставкаget
,put
иpatch
Метод обработки запроса.
Унаследовано от:GenericAPIView
, RetrieveModelMixin
,UpdateModelMixin
RetrieveDestroyAPIView
Как запрашивать, так и удалять отдельные экземпляры
поставкаget
иdelete
Метод обработки запроса.
Унаследовано от:GenericAPIView
, RetrieveModelMixin
,DestroyModelMixin
RetrieveUpdateDestroyAPIView
В то же время поддержка запроса, обновления, удаления
поставкаget
,put
,patch
иdelete
Метод обработки запроса.
Унаследовано от:GenericAPIView
, RetrieveModelMixin
,UpdateModelMixin
,DestroyModelMixin
Пользовательский универсальный класс представления
Часто вы захотите использовать существующее универсальное представление и немного настроить поведение. Если вы обнаружите, что повторно используете некоторое пользовательское поведение в нескольких местах, вам может потребоваться реорганизовать поведение в обычный класс, а затем применить его к любому представлению или набору представлений по мере необходимости.
пользовательские миксины
Например, если вам нужно найти объекты на основе нескольких полей в конфигурации URL, вы можете создать класс миксина.
Возьмите каштан:
class MultipleFieldLookupMixin(object):
"""
将此 mixin 应用于任何视图或视图集以获取多个字段过滤
基于`lookup_fields`属性,而不是默认的单个字段过滤。
"""
def get_object(self):
queryset = self.get_queryset() # 获取基本的查询集
queryset = self.filter_queryset(queryset) # 使用过滤器
filter = {}
for field in self.lookup_fields:
if self.kwargs[field]: # 忽略空字段
filter[field] = self.kwargs[field]
obj = get_object_or_404(queryset, **filter) # 查找对象
self.check_object_permissions(self.request, obj)
return obj
Затем примесь можно применить к представлению или набору представлений всякий раз, когда необходимо применить пользовательское поведение.
class RetrieveUserView(MultipleFieldLookupMixin, generics.RetrieveAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
lookup_fields = ('account', 'username')
Использование пользовательских миксинов — хороший вариант, если вам нужно использовать настраиваемое поведение.
пользовательский базовый класс
Если вы используете миксин в нескольких представлениях, вы можете сделать еще один шаг, создав собственный набор базовых представлений, а затем использовать их в своем проекте. Например:
class BaseRetrieveView(MultipleFieldLookupMixin,
generics.RetrieveAPIView):
pass
class BaseRetrieveUpdateDestroyView(MultipleFieldLookupMixin,
generics.RetrieveUpdateDestroyAPIView):
pass
Использование настраиваемого базового класса — хороший вариант, если настраиваемое поведение всегда необходимо повторно использовать в большом количестве представлений по всему проекту.