【发布时间】:2018-10-20 18:20:45
【问题描述】:
通常,当我使用 ModelViewSet 导航到 url http://localhost:8000/api/v1/public_profiles/ 时,我只会得到一个 POST 表单,而当我导航到 http://localhost:8000/api/v1/public_profiles/123456/ 等特定资源时,我只会得到一个 PUT/PATCH 表单。 目前这两个表单都在两个位置呈现。
对于我的许多路线,我需要对视图进行更多控制,因此我选择了通用视图。我还想利用路由器,所以我混合了一个通用的视图集。上图是实现以下视图的结果:
class PublicProfileViewSet(viewsets.GenericViewSet, generics.ListCreateAPIView, generics.RetrieveUpdateAPIView):
queryset = PublicProfile.objects.all()
def get_serializer_class(self):
if self.action == 'list':
return PublicProfileReadSerializer
elif self.action == 'retrieve':
return PublicProfileReadSerializer
elif self.action == 'create':
return PublicProfileCreateSerializer
elif self.action == 'update':
return PublicProfileUpdateSerializer
else:
return PublicProfileReadSerializer
我能做些什么来解决这个问题,以便 POST 表单在 LIST 操作上呈现,而 PUT/PATCH 表单在 RETRIEVE 操作上呈现?
我尝试过的一件事是使用 ViewSet,但由于没有“serializer_class”,因此我没有生成任何表单:
class PublicProfileViewSet(viewsets.ViewSet):
def list(self, request):
queryset = PublicProfile.objects.all()
serializer = PublicProfileReadSerializer(queryset, many=True, context={'request': request})
return Response(serializer.data)
def retrieve(self, request, pk=None):
queryset = PublicProfile.objects.all()
public_profile = get_object_or_404(PublicProfile, pk=pk)
serializer = PublicProfileReadSerializer(public_profile, context={'request': request})
return Response(serializer.data)
def create(self, request):
serializer = PublicProfileCreateSerializer(data=request.data, context={'request': request})
if serializer.is_valid(raise_exception=True):
serializer.save()
return Response(serializer.data)
def update(self, request, pk=None):
instance = get_object_or_404(PublicProfile, pk=pk)
serializer = PublicProfileUpdateSerializer(instance, data=request.data, context={'request': request})
if serializer.is_valid(raise_exception=True):
serializer.save()
return Response(serializer.data)
def partial_update(self, request, pk=None):
instance = get_object_or_404(PublicProfile, pk=pk)
serializer = PublicProfileUpdateSerializer(instance, data=request.data, context={'request': request}, partial=True)
if serializer.is_valid(raise_exception=True):
serializer.save()
return Response(serializer.data)
def destroy(self, request, pk=None):
instance = get_object_or_404(PublicProfile, pk=pk)
instance.user.is_active = False
instance.user.save()
return Response(status=status.HTTP_200_OK)
【问题讨论】:
-
为什么不将视图分成 2 个视图。一个用于
ListCreate,另一个用于RetrieveUpdate -
@PeterSobhi 这会如何影响我的路由器?
标签: django django-rest-framework