web-dev-qa-db-fra.com

Django Champ de mise à jour de Rest Framework

Je suis nouveau sur DRF et j'essaie d'écrire une vue/sérialisation personnalisée que je peux utiliser pour mettre à jour un seul champ d'objet utilisateur.

J'ai besoin de faire de la logique juste pour mettre à jour le "nom" de l'utilisateur.

J'ai écrit le sérialiseur:

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

Cette méthode n'est jamais appelée. J'ai essayé de définir un point d'arrêt là-bas et de le déboguer, mais il n'est jamais appelé, même si j'utilise les méthodes PUT, POST ou PATCH. Si j'ajoute la méthode create, elle est utilisée appelé lorsque j'utilise POST.

Voici à quoi ressemble ma vue:

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

Quelqu'un a-t-il une suggestion? Merci!

Mon models.py ressemble à ceci

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)
29
Boban

La définition des méthodes que le noeud final peut accepter se fait dans la vue, pas dans le sérialiseur.

La méthode de mise à jour que vous avez sous votre sérialiseur doit être déplacée dans votre vue afin que vous ayez quelque chose comme:

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)

Notez que vous remplacez le pdateModelMixin et vous devrez peut-être modifier un peu le code ci-dessus pour le faire correctement.

26
awwester

Si vous utilisez class UpdateName(generics.CreateAPIView), cela n'appellera qu'une méthode create() sur le sérialiseur.

Vous devez sous-classe generics.UpdateAPIView au lieu. Et c'est tout. Vous n'avez pas à déplacer votre méthode dans la vue comme suggéré dans cette réponse (il s'agit essentiellement de copier/dupliquer la méthode de mise à jour de UpdateModelMixin)

Pour plus d'informations sur le fonctionnement des sérialiseurs concernant l'enregistrement/la mise à jour voir la documentation ici:

1
Tadej Krevh