Django DRF @action 装饰器
@action
装饰器在Django REST Framework (DRF) 中非常有用,它可以帮助你在ViewSet中创建自定义的动作,而不仅仅是依赖标准的CRUD操作(Create, Read, Update, Delete)。以下是
@action
装饰器的一些常见用法:
1. 创建自定义集合动作
detail=False
表示这个动作是针对整个集合的。例如,你可以创建一个获取所有用户统计信息的动作:
from rest_framework.decorators importactionfrom rest_framework.response importResponsefrom rest_framework importviewsetsclassUserViewSet(viewsets.ModelViewSet):
queryset=User.objects.all()
serializer_class=UserSerializer
@action(detail=False, methods=['get'])defstatistics(self, request):
user_count=User.objects.count()return Response({'user_count': user_count})
2. 创建自定义实例动作
detail=True
表示这个动作是针对单个实例的。例如,你可以创建一个标记用户为活跃的动作:
from rest_framework.decorators importactionfrom rest_framework.response importResponsefrom rest_framework importviewsetsclassUserViewSet(viewsets.ModelViewSet):
queryset=User.objects.all()
serializer_class=UserSerializer
@action(detail=True, methods=['post'])def activate(self, request, pk=None):
user=self.get_object()
user.is_active=True
user.save()return Response({'status': 'user activated'})
3. 支持多种HTTP方法
你可以指定动作支持的HTTP方法。例如,你可以创建一个既支持GET又支持POST的动作:
from rest_framework.decorators importactionfrom rest_framework.response importResponsefrom rest_framework importviewsetsclassUserViewSet(viewsets.ModelViewSet):
queryset=User.objects.all()
serializer_class=UserSerializer
@action(detail=False, methods=['get', 'post'])defcustom_action(self, request):if request.method == 'GET':return Response({'message': 'This is a GET request'})elif request.method == 'POST':
data=request.datareturn Response({'message': 'This is a POST request', 'data': data})
4. 指定URL路径和名称
你可以指定自定义动作的URL路径和名称。例如:
from rest_framework.decorators importactionfrom rest_framework.response importResponsefrom rest_framework importviewsetsclassUserViewSet(viewsets.ModelViewSet):
queryset=User.objects.all()
serializer_class=UserSerializer
@action(detail=True, methods=['post'], url_path='set-password', url_name='set_password')def set_password(self, request, pk=None):
user=self.get_object()
new_password= request.data.get('password')
user.set_password(new_password)
user.save()return Response({'status': 'password set'})
5. 使用权限和认证
你可以为自定义动作设置权限和认证。例如:
from rest_framework.decorators importactionfrom rest_framework.response importResponsefrom rest_framework importviewsetsfrom rest_framework.permissions importIsAuthenticatedclassUserViewSet(viewsets.ModelViewSet):
queryset=User.objects.all()
serializer_class=UserSerializer
@action(detail=True, methods=['get'], permission_classes=[IsAuthenticated])def profile(self, request, pk=None):
user=self.get_object()
serializer=self.get_serializer(user)return Response(serializer.data)
6. 返回自定义响应
你可以在自定义动作中返回任何类型的响应。例如,文件下载、重定向等:
from rest_framework.decorators importactionfrom rest_framework.response importResponsefrom rest_framework importviewsetsfrom django.http importFileResponseclassDocumentViewSet(viewsets.ModelViewSet):
queryset=Document.objects.all()
serializer_class=DocumentSerializer
@action(detail=True, methods=['get'])def download(self, request, pk=None):
document=self.get_object()
file_handle=document.file.open()
response= FileResponse(file_handle, content_type='application/pdf')
response['Content-Disposition'] = f'attachment; filename="{document.filename}"' return response
总结
@action
装饰器为Django REST Framework中的ViewSet提供了极大的灵活性,允许你在标准的CRUD操作之外添加自定义逻辑和功能。这使得你能够创建更加丰富和复杂的API端点,满足具体的业务需求。