Search code examples
pythondjangodjango-rest-frameworkdjango-serializerdjoser

Can one inherit a ModelSerializer and Merge Models


I am trying to inherit djoser's UserCreatePasswordRetypeSerializer

Djoser Modelserializer's model is User. The child Serializer that I am implementing represents a different model, Customer.

So could one do:

class CustomerSerializer(UserCreatePasswordRetypeSerializer):
     class Meta:
        model=Customer
        fields = ('customer_name',)+UserCreatePasswordRetypeSerializer.Meta.fields

When I do this django is complaining because Customer model does not have the model fields that User has.

this is the customer model but this model does exactly represent this model.

 class Customer(models.Model):
        customer_name = models.CharField(max_length=255) 
        user = models.ForeignKey(User,on_delete=models.CASCADE,related_name='user')

Would passing User as a parent class solve this issue?

class Customer(User):
        customer_name = models.CharField(max_length=255) 

would this work with inherited ModelSerializers.

As Djoser is an app I can not change the UserCreatePasswordRetypeSerializer to fit my needs.

I can either inherit is or

this is the second approach i was thinking.

create something like,

class CustomerSerializer(serializers.ModelSerializer):
    
    user=UserCreatePasswordRetypeSerializer
    class Meta:
        fields = ('customer_name','user')

since this is a nested serializer I will have to write create method myself.

the issue is how can I call the create of the UserCreatePasswordRetypeSerializer in the create method that I implement because I need to use the create method of UserCreatePasswordRetypeSerializer since it handles sending emails and all the other features in the serializer. So I can not basically just pop the validated data of user and create the user object in CustomerSerializer's create method like so:

user_validated_data=validated_data.pop('user')
User.objects.create(**user_validated_data).

I have to call the create method of UserCreatePasswordRetypeSerializer but Since I am not inheriting that Serializer i can not just call super().create(user_validated_data).

Again I can not inherit it because Child and Parents represent different models.


Solution

  • Would passing User as a parent class solve this issue?

    Yes. When Customer inherits User, it will get all the fields User has.

    The question however is whether that's necessary. Does the serializer need all of User fields to function? If not, or possibly even if, it might be more efficient to just add the necessary fields to Customer directly.

    Keep in mind that when Customer inherits User, every Customer instance you create will also create a User instance. And when you query a Customer instance, Django will do a JOIN on the User table to fetch the required fields - as described in the docs under multi-table inheritance. Sometimes this is beneficial, sometimes it's an impediment on database efficiency - it really depends on your specific use-case; the number of columns, how well you've indexed your tables, and so on.

    My suggestion to you is to add whatever fields the serializer requires to Customer and then go with your initial attempt:

    # serializers.py
    class CustomerSerializer(UserCreatePasswordRetypeSerializer):
         class Meta:
            model=Customer
            fields = ('customer_name', # + other necessary fields)