Django Rest Framework更新字段

时间:2015-07-01 23:32:17

标签: django django-rest-framework

我是DRF的新手,我正在尝试编写自定义视图/序列化程序,我只能用它来更新用户对象的一个​​字段。

我需要制作逻辑只是为了更新"名称"用户。

我写了序列化器:

class ClientNameSerializer(serializers.ModelSerializer):
    class Meta:
        model = ClientUser
        fields = ('name',)

    def update(self, instance, validated_data):
        instance.name = validated_data.get('name', instance.name)
        instance.save()
        return instance

永远不会调用此方法。我尝试在那里设置断点并调试它,但它永远不会被调用,即使我使用PUT,POST或PATCH方法。如果我添加创建方法,则在使用POST时会调用它。

这就是我的观点:

class UpdateName(generics.CreateAPIView):
    queryset = ClientUser.objects.all()
    serializer_class = ClientNameSerializer
    permission_classes = (permissions.IsAuthenticated,)

有人有什么建议吗?谢谢!

我的 models.py 看起来像这样

class ClientUser(models.Model):
    owner = models.OneToOneField(User,unique=True,primary_key=True)

    phone_number = models.CharField(validators=[PHONE_REGEX],max_length=20,unique=True)

    name = models.CharField(max_length=100,blank=True)
    status = models.IntegerField(default=1)
    member_from = models.DateTimeField('member from',auto_now_add=True)
    is_member = models.BooleanField(default=False)

3 个答案:

答案 0 :(得分:24)

端点可以接受的方法的定义在视图中完成,而不是在序列化器中完成。

您的序列化工具下的更新方法需要移至您的视图中,以便您具有以下内容:

<强> serializers.py

class ClientNameSerializer(serializers.ModelSerializer):
    class Meta:
        model = ClientUser

<强> views.py

class UpdateName(generics.UpdateAPIView):
    queryset = ClientUser.objects.all()
    serializer_class = ClientNameSerializer
    permission_classes = (permissions.IsAuthenticated,)

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        instance.name = request.data.get("name")
        instance.save()

        serializer = self.get_serializer(instance)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)

        return Response(serializer.data)

请注意,您已覆盖UpdateModelMixin并且可能需要稍微更改上述代码才能使其正确。

答案 1 :(得分:1)

如果使用class UpdateName(generics.CreateAPIView),则只会在序列化程序上调用create()方法。

您应该改为generics.UpdateAPIView的子类。就是这样。 您不必将方法移动为suggested in this answer到视图(它基本上是复制/复制UpdateModelMixin的update方法)

有关更多信息,请参见序列化程序如何保存/更新see the docs here:

答案 2 :(得分:0)

另一种方法可能是以下一种:

serializer.py

class ClientNameSerializer(serializers.ModelSerializer):
   class Meta:
        model = ClientUser
        fields = ('name',)

   def update(self, instance, validated_data): 
        instance.name = validated_data.get('name', instance.name)
        instance.save()
        return instance

views.py

class UpdateName(generics.UpdateAPIView):
    queryset = ClientUser.objects.all()
    serializer_class = ClientNameSerializer
    permission_classes = (permissions.IsAuthenticated,)

    def update(self, request, *args, **kwargs):
        data_to_change = {'name': request.data.get("name")}
        # Partial update of the data
        serializer = self.serializer_class(request.user, data=data_to_change, partial=True)
        if serializer.is_valid():
            self.perform_update(serializer)

        return Response(serializer.data)