How to update modified_by field with CurrentUserDefualt

i get this error when i am trying to update modified_by field

Tried to update field sales.CustomersTag.modified_by with a model instance, <SimpleLazyObject: <UserProfile: Admin>>. Use a value compatible with CharField.

this is my serializer.py:

class CustomersTagSerializer(serializers.ModelSerializer):
    created_by = serializers.CharField(read_only=True, default=serializers.CurrentUserDefault())
    modified_by = serializers.CharField(read_only=True, default=serializers.CurrentUserDefault())

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

    class Meta:
        model = models.CustomersTag
        fields = (
            'id',
            'name',
            'created_date',
            'modified_date',
            'created_by',
            'modified_by',
        )

and this my view.py:

class CustomerTagGetIdPutView(generics.RetrieveAPIView,
                              mixins.UpdateModelMixin):
    permission_classes = (AllowAny,)
    queryset = models.CustomersTag.objects.all()
    serializer_class = CustomersTagSerializer

    def get_object(self):
        id = self.kwargs['id']
        obj = generics.get_object_or_404(models.CustomersTag, id=id)
        return obj

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

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

i tried alot to solve this problem but i can't .. any one can help me for this problem

Upvotes: 1

Views: 1199

Answers (2)

hugobessa
hugobessa

Reputation: 546

If you're using Django REST Framework generic views and no overriding the behavior of methods like get_serializer or get_serializer_context, your serializer will receive a context object. This context object is a dictionary with the request and the view object.

That said, you can do this by overriding create() and update() in your serializer. For example:

class CustomersTagSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.CustomersTag
        fields = (
            'id',
            'name',
            'created_date',
            'modified_date',
            'created_by',
            'modified_by',
        )

    def create(self, validated_data):
        user = self.context['request'].user
        return models.CustomersTag.objects.create(
            created_by=user, **validated_data)

    def update(self, instance, validated_data):
        user = self.context['request'].user
        instance.name = validated_data.get('name', instance.name)
        instance.modified_by = user
        instance.save()
        return instance

But maybe if you want to maintain a log history of editions in your models you could use a package like django-auditlog.

Upvotes: 1

Xhens
Xhens

Reputation: 802

You can do this while calling save() in your model. For example:

class CustomersTagSerializer(serializers.ModelSerializer):
     created_by = models.ForeignKey(User, null=True, editable=False)
     modified_by = models.ForeignKey(User, null=True, editable=False)

def save(self, *args, **kwargs):
    user = get_current_user()
    if user and user.is_authenticated():
        self.modified_by = user
        if not self.id:
            self.created_by = user
    super(CustomersTagSerializer, self).save(*args, **kwargs)

Upvotes: 0

Related Questions