Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write only, read only fields in django rest framework

I have models like this:

class ModelA(models.Model):     name = models.CharField()   class ModelB(models.Model):     f1 = models.CharField()     model_a = models.ForeignKey(ModelA) 

Serializers:

class ASerializer(serializers.ModelSerializer):     model_b_ids = serializers.CharField()     class Meta:         model = ModelA         write_only_fields = ('model_b_ids',) 

views:

class AView(CreateModelMixin, GenericViewSet):      def perform_create(self, serializer):          model_b_ids = parse_somehow(serializer.validated_data["model_b_ids"])         #do something... 

The problem I am getting is the with the "model_b_ids"

The user should submit it while sending post data.

I use it in perform_create to link to related models.

But thats not "real column" in ModelA so when I try to save it is raising exception.

I tried to it pop from validated_data but then again getting error somewhere that cannot read model_b_ids from model. Any idea on using this kind of field correctly ?

like image 839
user1305989 Avatar asked Jan 25 '16 10:01

user1305989


People also ask

What is write only field Django REST framework?

From DRF v3 onwards, setting a field as read-only or write-only can use serializer field core arguments mentioned as follows. write_only. Set this to True to ensure that the field may be used when updating or creating an instance, but is not included when serializing the representation.

What is the difference between ModelSerializer and HyperlinkedModelSerializer?

The HyperlinkedModelSerializer class is similar to the ModelSerializer class except that it uses hyperlinks to represent relationships, rather than primary keys. By default the serializer will include a url field instead of a primary key field.

How do you make a field optional in a serializer?

By default it is set to False. Setting it to True will allow you to mark the field as optional during "serialization". Note: required property is used for deserialization.


2 Answers

The Django Rest Framework does not have Meta attribute write_only_fields anymore

According to their docs you set write-only fields in extra_kwargs

e.g

class UserSerializer(ModelSerializer):     """     ``Serializer`` for ``User`` ..     """      class Meta:         model = User         fields = ('id', 'email', 'first_name', 'last_name' ,'security_question', 'security_question_answer', 'password', 'is_active', 'is_staff')         read_only_fields = ('is_active', 'is_staff')         extra_kwargs = {             'security_question': {'write_only': True},             'security_question_answer': {'write_only': True},             'password': {'write_only': True}         } 

Update

As @AKHIL MATHEW highlighted in his answer below

From DRF v3 onwards, setting a field as read-only or write-only can use serializer field core arguments mentioned as follows.

write_only

Set this to True to ensure that the field may be used when updating or creating an instance, but is not included when serializing the representation.

Defaults to False Eg:

company = serializers.PrimaryKeyRelatedField(write_only=True)

like image 55
Dr Manhattan Avatar answered Oct 19 '22 06:10

Dr Manhattan


In accordance with the Django REST Framework documentation:

The write_only_fields option on ModelSerializer has been moved to PendingDeprecation and replaced with a more generic extra_kwargs

that's why it's recommended to do like this: you should use extra_kwargs:

extra_kwargs = {     'model_b_ids': {'write_only': True},     'another_field': {'read_only': True} } 

or:

 model_b_ids = serializers.IntegerField(write_only=True) 
like image 41
M.Void Avatar answered Oct 19 '22 06:10

M.Void