Django rest framework-其他
本文为学习官方文档时所做笔记,可以看做是官方文档的全文翻译
自定义混合类
-
自定义一个基于多个URL查询参数的创造混合类
class MultipleFieldLookupMixin(object): """ Apply this mixin to any view or viewset to get multiple field filtering based on a `lookup_fields` attribute, instead of the default single field filtering. """ def get_object(self): queryset = self.get_queryset() # Get the base queryset queryset = self.filter_queryset(queryset) # Apply any filter backends filter = {} for field in self.lookup_fields: if self.kwargs[field]: # Ignore empty fields. filter[field] = self.kwargs[field] obj = get_object_or_404(queryset, **filter) # Lookup the object 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']
查询是否已登录
-
通过
perform_createdef 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)
增加额外动作
-
@action装饰器from django.contrib.auth.models import User from rest_framework import status, viewsets from rest_framework.decorators import action from rest_framework.response import Response from myapp.serializers import UserSerializer, PasswordSerializer class UserViewSet(viewsets.ModelViewSet): """ A viewset that provides the standard actions """ queryset = User.objects.all() serializer_class = UserSerializer @action(detail=True, methods=['post']) def set_password(self, request, pk=None): user = self.get_object() serializer = PasswordSerializer(data=request.data) if serializer.is_valid(): user.set_password(serializer.data['password']) user.save() return Response({'status': 'password set'}) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @action(detail=False) def recent_users(self, request): recent_users = User.objects.all().order_by('-last_login') page = self.paginate_queryset(recent_users) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(recent_users, many=True) return Response(serializer.data)该装饰器也可以设置
@action(detail=True, methods=['post','delete'], permission_classes=[IsAdminOrIsSelf])建立了额外动作之后,将可以在
^users/{pk}/set_password/$或^users/{pk}/unset_password/$中访问到。一个视图的所有额外做的可以通过方法.get_extra_actions()来查询通过
@action设置的额外动作会自动注册到router中并产生相应的url地址,如上文的set_passwprd- URL path:
^users/{pk}/set_password/$,基于basename产生 - URL name:
'user-set-password'
如果想自定义这两个值,则需要在装饰器中自定义以下两个值
@action(methods=['post'], detail=True, permission_classes=[IsAdminOrIsSelf], url_path='change-password', url_name='change_password')产生的效果如下
- URL path:
^users/{pk}/change-password/$ - URL name:
change_password,完整名在前面加上basename,变为'users-change_password'
- URL path:
反向解析动作的URL
-
.get_extra_actions():从一个动作名得到其对应的url地址//#如果没有设置ViewSet及注册到router中,则需要手动设置basename >>> view.reverse_action('set-password', args=['1']) 'http://localhost:8000/api/users/1/set_password' >>> view.reverse_action(view.set_password.url_name, args=['1']) #set_password为设置的basename,url_name为@action装饰器中设置的的动作名(如果有) 'http://localhost:8000/api/users/1/set_password'

浙公网安备 33010602011771号