Raju In
Raju In

Reputation: 61

How to update fields of custom user model using Django serializer

I am trying to update the various fields of a user model when the user wants to update it which was created earlier. I am having a custom user model and I am using django rest framework for the update api.

views.py

class UserUpdate(generics.UpdateAPIView):
    """
    Update user.
    """
    parser_class = (FileUploadParser,)
    permission_classes = (AllowAny,)
    queryset = User.objects.all()
    serializer_class = UserUpdateSerializer

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        instance.user_id = request.data.get("user_id")
        instance.save()
        serializer = self.get_serializer(instance, data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)
        return Response(serializer.data)

models.py

class User(models.Model):
    USER_CHOICES = (
        (1, u'ADMIN'),
        (2, u'SALES'),
        (3, u'KITCHEN'),
        (4, u'EMPLOYEE'),
    )
    image = models.ImageField(upload_to='employees/', null = True, blank = True)
    name = models.CharField(max_length=50)
    user_id = models.CharField(max_length=30, primary_key = True, blank = False)
    email = models.CharField(max_length=50)
    password = models.CharField(max_length=100)
    is_active = models.BooleanField(default=True)
    user_group = models.PositiveSmallIntegerField(default=4, choices=USER_CHOICES)
    firebase_token = models.CharField(max_length=150, default=None, null = True)
    shop =  models.ForeignKey(Shop, on_delete=models.SET_DEFAULT, default=None)
    phone = PhoneField(blank=False, default=0)

serializers.py

class UserUpdateSerializer(serializers.ModelSerializer):
    shop = serializers.CharField()
    class Meta:
        model = User
        fields = ('image', 'url', 'phone', 'name', 'user_id','email', 'password', 'is_active', 'user_group', 'shop')

    def update(self, instance, validated_data):
        shop = validated_data.pop('shop')
        user_id = validated_data.pop("user_id")
        print(user_id)
        shopId = Shop.objects.filter(name=shop).values('shop_id').first()
        if shopId is not None:
            shop_id = shopId['shop_id']
            try:
                if user_id is not None:
                    instance.name = validated_data.get('name', instance.name)
                    instance.image = validated_data.get('image', instance.image)
                    instance.email = validated_data.get('email', instance.email)
                    instance.phone = validated_data.get('phone', instance.phone)
                    instance.password = validated_data.get('password', instance.password)
                    instance.user_group = validated_data.get('user_group', instance.user_group)
                    instance.shop_id = validated_data.get('shop_id', instance.shop_id)
                    instance.is_active =  True
                    instance.save()
                    return instance
                else:
                    print("Test")
            except Exception as e:
                return e
        else:
            return None

This is throwing an error saying that the user already exists!

Please assist!

Upvotes: 1

Views: 7470

Answers (2)

Hasan
Hasan

Reputation: 968

When you are calling UserUpdate API, it will create every new User for every new user_id. I don't know why you are updating user_id. Any new user_id will create a new User instance. If you want to update other than user_id, you need to remove the following line.

  1. Remove these lines from UserUpdate API View.

    instance.user_id = request.data.get("user_id")       
    instance.save()
    
  2. Remove this line from UserUpdateSerializer

    instance.user_id = validated_data.get('user_id', instance.user_id)
    
  3. Add lookup_field = 'user_id' to UserUpdate API view

  4. Add user_id at url, like

    path('userupdate/<str:user_id>/', UserUpdate.as_view())
    

Upvotes: 1

anjaneyulubatta505
anjaneyulubatta505

Reputation: 11695

Just Change your serializer like below

class UserUpdateSerializer(serializers.ModelSerializer):
    shop = serializers.CharField()

    class Meta:
        model = User
        fields = ('image', 'url', 'phone', 'name', 'user_id','email', 'password', 'is_active', 'user_group', 'shop')

    def update(self, instance, validated_data):
        shop = validated_data.pop('shop')
        shop_obj = Shop.objects.filter(name=shop).first()
        if shop_obj:
            instance.shop = shop_obj
        return super().update(instance, validated_data)

Upvotes: 3

Related Questions