Reputation: 5776
I have a ModelSerializer
. I was trying to set a user foreign key when saving a model, instantiated via the create()
and update()
methods of a ModelViewSet
class. Eg:
ModelViewSet:
def create(self, request):
serializer = self.get_serializer(data=request.data, many=isinstance(request.data, list))
if not serializer.is_valid():
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
Serializer
def process_foreign_keys(self, validated_data):
""" Simplified for SO example """
profile = get_object_or_404(Profile, fk_user=CurrentUserDefault())
validated_data['profile'] = profile
return validated_data
def create(self, validated_data):
""" Create a Product instance. Routed from POST via DRF's serializer """
validated_data = self.process_foreign_keys(validated_data)
return Product.objects.create(**validated_data)
That code doesn't work - it throws an exception on the get_object_or_404
line:
int() argument must be a string, a bytes-like object or a number, not 'CurrentUserDefault'
If I put a few debugging statements in the ModelSerializer.create()
method, I get weird stuff:
currentuser = CurrentUserDefault()
# Expect <class django.contrib.auth.models.User>, get <class 'rest_framework.fields.CurrentUserDefault'>
print("currentuser type " + str(type(currentuser)))
# Causes AttributeError: 'CurrentUserDefault' object has no attribute 'user'
print("currentuser is " + str(currentuser.__call__()))
# Causes AttributeError: 'ProductSerializer' object has no attribute 'request'
print("currentuser is " + str(self.request.user))
All this was done while a user was logged in, so it's not an AnonymousUser
problem.
What am I screwing up? How do I get the current user in a serializer
instantiated within the create
/update
methods of a ModelViewSet
via self.get_serializer()
?
Edit: Attempting with a HiddenField
doesn't seem to work either. From the docs :
"
HiddenField: This field will be present in validated_data but will not be used in the serializer output representation.
"
So I set as a ModelSerializer
class field:
currentuser = serializers.HiddenField(default=serializers.CurrentUserDefault())
... and then attempt validated_data.get('currentuser')
in the update
method, and that returns None
.
Upvotes: 2
Views: 1659
Reputation: 1493
def create(self, request):
serializer = self.get_serializer(data=request.data, many=isinstance(request.data, list), context={"request": request})
can you change you serializer
instantiation to above code and use it as below:
profile = get_object_or_404(Profile, fk_user=self.request.user)
Upvotes: 1
Reputation: 20976
CurrentUserDefault
is not a magic method that gets the user out of the void. It has to be within the context of a field a shown in the documentation
As @pramod pointed out, you need to either:
get_object_or_404(Profile, fk_user=self.request.user)
or set a CurrentUserDefault
as a default value for a field.
Upvotes: 1