2017-10-09 2 views
0

Je veux mettre à jour l'instance profil d'un utilisateur, en envoyant des données à l'update_profile url/Django reste la création par exemple un profil au lieu de mettre à jour le profil

J'utilise:

curl -X PUT -H "Authorization: Token sometoken" -d "name=somename&age=20&user=1" 127.0.0.1:8000/update_profile/ 

et l'erreur J'obtiens is: {"user": ["Ce champ doit être unique."]}

Il semble que l'erreur survienne parce que la requête crée une nouvelle instance de Profile, quand il y a déjà une autre instance de Profile avec cette même utilisateur. Mais je veux juste mettre à jour l'instance de profil en cours pour l'utilisateur. Une idée de pourquoi mon code essaie de créer une nouvelle instance au lieu de la mettre à jour?

views.py

class UserProfileChangeAPIView(generics.UpdateAPIView, mixins.UpdateModelMixin): 

    permission_classes = (
    permissions.IsAuthenticated, 
    UserIsOwnerOrReadOnly, 
    ) 
    serializer_class = UpdateProfileSerializer 
    parser_classes = (MultiPartParser, FormParser,) 

    def get_queryset(self, *args, **kwargs): 
     queryset = Profile.objects.filter(user=self.request.user) 
     return queryset 

    def get_object(self): 
     self.request.user.profile 

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

    def delete(self, request, *args, **kwargs): 
     return self.destroy(request, *args, **kwargs) 

    def update(self, request, pk=None): 
     try: 
      self.request.user.profile 

     except Http404: 
      return Response(
       {'detail': 'Not found'}, status=status.HTTP_404_NOT_FOUND) 
     return super(UserProfileChangeAPIView, self).update(request, pk) 

urls.py

 url(r'^update_profile/$', UserProfileChangeAPIView.as_view(), name='update_profile'), 

serializers.py

class UpdateProfileSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Profile 
     fields = [ 
      'name', 
      'age', 
      'user', 
     ] 

models.py

class Profile(models.Model): 
    user = models.OneToOneField(User, on_delete=models.CASCADE) 
    name = models.CharField(max_length=100, null=True) 
    age = models.PositiveIntegerField(null=True) 

Répondre

0

I a pu résoudre le problème comme celui-ci et pas besoin de pk dans l'url:

serializers.py

class UpdateProfileSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Profile 
     fields = [ 
      'name', 
      'age', 
     ] 

views.py

class ProfileUpdateAPIView(UpdateAPIView): 
    serializer_class = UpdateProfileSerializer 

    def get_object(self): 
     queryset = Profile.objects.filter(user=self.request.user) 
     obj = queryset[0] 
     return obj 

urls.py:

url(r'^update/$', ProfileUpdateAPIView.as_view(), name='update'), 

boucle:

curl -X PUT -H "Authorization: Token sometoken" -d "name=newname&age=20" 127.0.0.1:8000/update/ 
0

Vous ne devriez pas inclure un user dans les données post que vous êtes déjà obtenir le profil de l'utilisateur connecté actuel utilisateur dans get_object() et get_queryset()

Parce que la relation entre le profil et l'utilisateur est un OnetoOneField, il ne peut pas être plus d'un Profile lié au même User.

Je me attends (de l'erreur que vous avez reçu) ce qui se passe ici est que votre connecté comme un User (par exemple id 3), puis essayer de mettre à jour le Profile pour pointer vers User id 1.

+0

Il semble que l'id est pas la raison de ce problème, car il est le même utilisateur que pour l'utilisateur qui envoie la demande . Si j'oublie l'utilisateur dans le sérialiseur et dans les données put, cette erreur apparaît: La contrainte NOT NULL a échoué: rest_auth_profile.user_id – DevB2F