Reputation: 2614
I wanted to make email field unique in default django User model. So i made it unique_together=[('email',)]
. Now in serializer I want it to be a read_only field.
But Django Rest Framework 3.0 docs says:
There is a special-case where a read-only field is part of a unique_together constraint at the model level. In this case the field is required by the serializer class in order to validate the constraint, but should also not be editable by the user.
The right way to deal with this is to specify the field explicitly on the serializer, providing both the read_only=True and default=… keyword arguments.
One example of this is a read-only relation to the currently authenticated User which is unique_together with another identifier. In this case you would declare the user field like so:
user = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault())
serializers.CurrentUserDefault() represents the current user.I want to set default as user's email . Isn't serializers.CurrentUserDefault()
equivalent to request.user
. serializers.CurrentUserDefault().email
is giving error 'CurrentUserDefault' object has no attribute 'email'
How to set email default as user's email ?
Upvotes: 3
Views: 3272
Reputation: 31
Please check solution 2 from this answer
The code can be:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'email',)
extra_kwargs = {
'email': {'read_only': True},
}
def create(self, validated_data):
"""Override create to provide a email via request.user by default."""
if 'email' not in validated_data:
validated_data['email'] = self.context['request'].user.email
return super(UserSerializer, self).create(validated_data)
hope it help :)
Upvotes: 2
Reputation: 2254
This is what the documentation of CurrentUserDefault
says:
A default class that can be used to represent the current user. In order to use this, the 'request' must have been provided as part of the context dictionary when instantiating the serializer.
You can either do that or you can provide the email id passed in the context data
in your views
. Override the function get_serializer_context
def get_serializer_context(self):
context = super(YourClass, self).get_serializer_context()
context['email'] = request.user.email
return context
in your views
. Your view
should be extended from GenericAPIView
at some level of inheritance. Now in your serializer
, override your __init__
and get your email data.
def __init__(self, instance = None, data = serializers.empty, *args, **kwargs):
self.email = kwargs['context']['email']
Now you can use that in your serializer.
Upvotes: 2