Reputation: 14814
I want to automatically assign a value for a required field in Django Rest framework, without the value having to be given in the post request.
My View:
class WaitercallCreate(CreateAPIView):
serializer_class = WaitercallCreateSerializer
permission_classes = (IsAuthenticated, )
The Serializer:
class WaitercallCreateSerializer(serializers.ModelSerializer):
class Meta:
model = Waitercall
fields = ('order', 'user', 'done', 'type_of_call')
read_only_fields = ('user', 'done')
Users should be able to do a postrequest, only giving their token in the header and the order id as the body. I want to set the value for user by default to the requests user. I tried overwriting the perform_create method in my view like this:
def perform_create(self, serializer):
serializer.save(user=self.request.user)
This didn't work. Then I tried overwriting the create method in the view like this:
def create(self, request, *args, **kwargs):
data = request.data
data['user'] = request.user
serializer = self.get_serializer(data=data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
Which also didn't work, because Orderdicts are immutable. For the first (and the last try, read further) I always get the same response:
{
"user": [
"This field is required."
]
}
Lastly I found this stackoverflow post, which recommends overwriting the create method in the serializer. Like this:
def create(self, validated_data):
print(self.context['request'].user)
validated_data['user'] = self.context['request'].user
return super(WaitercallCreateSerializer, self).create(validated_data)
It also gave me the same response. I'm lost. What can I try next?
Upvotes: 1
Views: 1805
Reputation: 420
I was also having same issue as yours. If you are using Generic views then do this:
Views:
def perform_create(self, serializer):
serializer.save(user=self.request.user)
Serializer:
You just have to add this in you serializer in order to save the user. PrimaryKeyRelatedField
is used to represent the target of the relationship using its primary key. read_only=True
to make this field read only.
class WaitercallCreateSerializer(serializers.ModelSerializer):
user = serializers.PrimaryKeyRelatedField(read_only=True)
class Meta:
model = Waitercall
fields = ('order', 'user', 'done', 'type_of_call')
Upvotes: 2
Reputation: 2819
The error is coming from the serializer validation, which is called before the create
method is called. Therefore, the changes to the create
method are not making a difference. You can fix this by calling out that the user
field is not required in the serializer. This will look like:
from rest_framework import serializers
class WaitercallCreateSerializer(serializers.ModelSerializer):
user = serializers.JSONField(required=False)
class Meta:
model = Waitercall
fields = ('order', 'user', 'done', 'type_of_call')
read_only_fields = ('user', 'done')
Upvotes: 4