Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call serializer's create() method from one serializer

I have two serializers, "UserSerializer" and "CustomerSerializer" as bellow

class UserSerializer(serializers.ModelSerializer):

    def create(self, validated_data):
        return User.objects.create(**validated_data)

    class Meta:
        model = User
        fields = '__all__'


class CustomerSerializer(serializers.ModelSerializer):

    def create(self, validated_data):
        return Customer.objects.create(**validated_data)

    class Meta:
        model = Customer
        fields = '__all__'

When I hit user api with POST request, it calls UserSerializer's create method which saves user object.

Now while saving user I want to save customer object as well, using user api. So for from UserSerializer's create method I want to call CustomerSerializer's create() method in order to save customer object as well. How do I do that ?

like image 467
Sunny Chaudhari Avatar asked Jan 19 '17 06:01

Sunny Chaudhari


People also ask

How do I pass Queryset to serializer?

How do I pass Queryset to serializer? To serialize a queryset or list of objects instead of a single object instance, you should pass the many=True flag when instantiating the serializer. You can then pass a queryset or list of objects to be serialized.

What does serializer Is_valid () do?

The .is_valid() method takes an optional raise_exception flag that will cause it to raise a serializers.ValidationError exception if there are validation errors.

Which class allows you to automatically create a serializer?

The ModelSerializer class provides a shortcut that lets you automatically create a Serializer class with fields that correspond to the Model fields.


2 Answers

You can call the CustomerSerializer from the create method inside the UserSerializer. E.G.

class UserSerializer(serializers.ModelSerializer):

    def create(self, validated_data):
        customer_serializer = CustomerSerializer(validated_data.get('customer'))
        customer_serializer.save()
        return User.objects.create(**validated_data)

    class Meta:
        model = User
        fields = '__all__'
like image 68
Edwin Lunando Avatar answered Oct 12 '22 13:10

Edwin Lunando


@Edwin...The solution is perfect just the thing I have made some changes in my data dictionary and send it to "CustomerSerializer" as bellow, and it started working. Thanks for your help and bellow code works for me now.

class UserSerializer(serializers.ModelSerializer):
    def get_serializer_context(self):
        return self.context['request'].data

    def create(self, validated_data):

        request_data = dict(self.get_serializer_context())

        cust_req_data = {'first_name':request_data['first_name'][0], 
                         'last_name':request_data['last_name'][0],
                         'email':request_data['email'][0]
                        }

        customer_serializer = CustomerSerializer(data=cust_req_data)
        if customer_serializer.is_valid():
            customer_serializer.save()

        return User.objects.create(**validated_data)

class Meta:
    model = User
    fields = '__all__'


class CustomerSerializer(serializers.ModelSerializer):

    def create(self, validated_data):
        return Customer.objects.create(**validated_data)

    class Meta:
        model = Customer
        fields = '__all__'

Also "if customer_serializer.is_valid():" this condition is required before saving object using CustomerSerializer

I have added "data" which is dict which i need to validate for my customer data fields,

since as I have explained previously that this is POST request I'm sending some data which is required to store user using UserSerializer and some data is required to store customer using CustomerSerializer using one user api itself.

so "get_serializer_context" method gives the entire post request data from that I get only those fields which are required to save customer and I have passed that dict as parameter to CustomerSerializer

"customer_serializer = CustomerSerializer(data=cust_req_data)"

This works for me.

like image 41
Sunny Chaudhari Avatar answered Oct 12 '22 13:10

Sunny Chaudhari