Home > Back-end >  how to override _default manager used by ModelSerializer
how to override _default manager used by ModelSerializer

Time:01-13

Given below snippet,

class CustomManager(models.Manager):
   def create(**kwargs):
       super().create(external_id='xyz', **kwargs)

class Person(models.Model):
   internal_id = models.AutoField(db_column='id', primary_key=True)
   f_name=models.CharField(db_column='f_name', max_length=15, blank=True, null=True)
   external_id = models.CharField(db_column='ext_id', null=True, blank=True, max_length=20)
   objects = models.Manager()
   custom = CustomManager()


class PersonSerializer(serializer.ModelSerializer):
   class Meta:
     model=Person
     fields='__all__'


Here, when .save() method gets called on the serializer, the default manager used by the the create function in serializer is objects. I would like this to be changed to custom so that when save call happens, create function inside CustomManager gets invoked.

I can achieve this by overriding the super class method create in the serializer. But is there any better workaround for this without overriding base class method?

CodePudding user response:

If you look serializer's save method it will call either create or update for your request. Actually, you have two way to achieve this. First, override serializer create method;

# serializers.py

class PersonSerializer(serializer.ModelSerializer):
   class Meta:
     model = Person
     fields = "__all__"
   
   def create(self, validated_data):
       # create an instance with your custom code and return it
       return instance

off subject: do not use "__all__", mostly it's not recommended. explicitly specify your fields.

And secondly, you can set your custom manager as default manager with default_manager_name. It might be helpful; Model.Meta.default_manager_name. The default value for default_manager_name is objects.

# managers.py

from django.db import models


class CustomManager(models.Manager):
    def create(self, **kwargs):
        # your logic here
        return obj

# models.py

class Person(models.Model):
    internal_id = models.AutoField(db_column='id', primary_key=True)
    f_name=models.CharField(db_column='f_name', max_length=15, blank=True, null=True)
    external_id = models.CharField(db_column='ext_id', null=True, blank=True, max_length=20)

    objects = models.Manager()
    custom = CustomManager()
    
    class Meta:
        default_manager_name = "custom"

But be careful because this method will be work only if you use create method like serializers do; Person._default_manager.create(**kwargs).

Lastly, you need to run Django's makemigrations and migrate commands.

  • Related