Reputation: 11656
I have a model which has a OneToOneField like this:
class Customer(models.Model):
"""A Class to represent a Customer in System """
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
The serializer for which looks like this:
class CustomerSerializer(serializers.ModelSerializer):
"""A Serizlier class for customer """
class Meta:
model = models.Customer
fields = ('user', 'first_name', 'last_name', 'dob', 'gender')
Right now the browsable api shows a dropdown list for user
how can I set user
to currently logged in user in CustomerSerializer
and make it read_only ? i.e the field should not be a passable parameter to the endpoint and instead should be a read only field corresponding to currently logged in user.
Upvotes: 0
Views: 261
Reputation: 88689
First of all, you should set the user
to a read_only
field. By doing so, you can't alter the value from API. This can be done by specifying read_only=True
in the field OR done by adding the read_only_fields
in the serializer's Meta class.
class CustomerSerializer(serializers.ModelSerializer):
"""A Serizlier class for customer """
class Meta:
model = models.Customer
fields = ('user', 'first_name', 'last_name', 'dob', 'gender')
read_only_fields = ('user',)
Thus, DRF won't accept any input to the user
field from your JSON payload that you are POSTing.
Customer
instance creation?I assume that you are using ModelViewset
view, so that it will pass the request
object and view
object to the corresponding serializer. In serializer we can access the context data by context
class variable of the serializer.
So, override the create()
method of CustomerSerializer
as below (I'm adding the complete config of the serializer bellow)
class CustomerSerializer(serializers.ModelSerializer):
"""A Serizlier class for customer """
class Meta:
model = models.Customer
fields = ('user', 'first_name', 'last_name', 'dob', 'gender')
read_only_fields = ('user',) # added <<<<
def create(self, validated_data): # override this method <<<
"""
Since the 'user' is a read_only field, the validated data doesn't contain it.
"""
user = self.context['request'].user
validated_data['user'] = user
return super().create(validated_data)
Upvotes: 2
Reputation: 1361
You can do it by overriding get_fields(self) of CustomerSerializer. Passing Current request user and filter user quer
class CustomerSerializer(serializers.ModelSerializer):
class Meta:
model = Customer
fields = ['user', 'first_name', 'last_name']
def get_fields(self):
fields = super().get_fields()
current_user = self.context['request'].user
fields['user'] = serializers.PrimaryKeyRelatedField(queryset=User.objects.filter(id=current_user.id))
return fields
Upvotes: 0
Reputation: 4146
I would limit choices in viewset.
class MyViewset(ViewSet):
serializer_class = CustomerSerializer
def get_queryset(self):
return Customer.objects.filter(user=self.request.user)
Upvotes: 0