2016-08-23 88 views
0

我试图用更新的方法后一个配置文件对象,但我得到一个错误消息,试图挽救我的串行时:Django的REST框架保存串行失败,POST方法

You cannot call `.save()` after accessing `serializer.data`.If you need to access data before committing to the database then inspect 'serializer.validated_data' instead. 

我的观点:

class SettingsProfileView(APIView): 
    """ 
    Get and update user profile 
    """ 
    queryset = models.UserProfile.objects.all() 
    serializer_class = serializers.UserProfileSerializer 

    renderer_classes = [TemplateHTMLRenderer] 
    template_name = 'base_/settings/profile.html' 

    def get_object(self, pk): 
     try: 
      return models.UserProfile.objects.get(pk=pk) 
     except models.UserProfile.DoesNotExist: 
      raise Http404 

    def get(self, request, format=None): 
     if not request.user.is_authenticated: 
      return Response({"error": _("User is not connected")}, status=status.HTTP_511_NETWORK_AUTHENTICATION_REQUIRED) 

     try: 
      profile = request.user.profile 
     except models.UserProfile.DoesNotExist: 
      profile = models.UserProfile(user=request.user) 
      profile.key_name = request.user.username 
      profile.save() 

     profile = self.get_object(request.user.profile.id) 
     serializer = serializers.UserProfileSerializer(profile) 
     return Response({'serializer': serializer, 'profile': profile}) 


    def post(self, request, format=None): 
     serializer = serializers.UserProfileSerializer(data=request.data) 
     if serializer.is_valid(): 
      serializer.save() 
      return Response(serializer.data, status=status.HTTP_201_CREATED) 
     return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 

发生在这个部分的错误:serializer.save()在我的post方法中。是否因为序列化程序正在用他的检测方法访问数据? 我的串行非常基本的,它没有特殊的代码:

class UserProfileSerializer(serializers.ModelSerializer): 

    class Meta: 
     model = UserProfile 
     fields = ('user', 'coachs', 'is_coach', 'gender', 'weight', 'height', 'visibility',) 

也许问题来自于一个事实,我使用后梅索德,而不是更新?

EDIT(后@pleasedontbelong后):

我已经与通用视图尝试:

class SettingsProfileView(generics.GenericAPIView): 

但更新方法不解雇(因为我来自一个HTML POST),所以我不得不手动提升更新方法,如下所示:

def post(self, request, *args, **kwargs): 
     return self.update(request, *args, **kwargs) 

def update(self, request, *args, **kwargs): 
     partial = kwargs.pop('partial', False) 
     instance = self.get_object(request.user.profile.id) 
     serializer = self.get_serializer(instance, data=request.data, partial=partial) 
     serializer.is_valid(raise_exception=True) 
     self.perform_update(serializer) 
     return Response(serializer.data) 

但是错误仍然是一样的。 我找不到任何例子,其中一个对象更新与django休息通过后期的方法。是否因为这不是一个好的方法?

回答

0

后调试的时间,它出现的问题来自于Visual Studio的断点。删除断点后,它工作正常。 也许Visual Studio尝试读取serializer.data,然后影响它们。

0

最好使用通用视图,它可以防止你重写所有这些代码。但是,如果你宁愿做手工,可以随时查询的源代码,以检查它是如何做:

https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/mixins.py#L61-L78

class UpdateModelMixin(object): 
    """ 
    Update a model instance. 
    """ 
    def update(self, request, *args, **kwargs): 
     partial = kwargs.pop('partial', False) 
     instance = self.get_object() 
     serializer = self.get_serializer(instance, data=request.data, partial=partial) 
     serializer.is_valid(raise_exception=True) 
     self.perform_update(serializer) 
     return Response(serializer.data) 

    def perform_update(self, serializer): 
     serializer.save() 

    def partial_update(self, request, *args, **kwargs): 
     kwargs['partial'] = True 
     return self.update(request, *args, **kwargs) 

您必须将用户配置实例传递到串行

BTW:你应该/必须使用PUT或PATCH进行更新,POST用于创建对象。

希望这有助于:)

+0

谢谢@pleasedontbelong我用你的建议编辑了这个问题,但我仍然有同样的错误。 – Ben