[Django]-Class reference inside class scope in python

2👍

This is actually a case for defining a metaclass.

I’ve never actually found a source of information which gives a complete, clear and satisfactory explanation as to what metaclasses are or how they work. I will try to enhance this answer with such information if required but for the time being I am going to stick to a solution for your present problem. I am assuming python 3.

Define an additional class, thus:

class ModelSerializerMeta(serializers.SerializerMetaclass):

    def __init__(cls, class_name, base_classes, attributes):

        super(ModelSerialiserMeta, cls).__init__(class_name, base_classes, attributes)
        Serializer.types[cls.Meta.oid] = [cls.Meta.model, cls]

Then use this as the metaclass of your Serializers, e.g.

class ProfileSerializer(serializers.ModelSerializer, metaclass=ModelSerializerMeta):

    class Meta:
        oid = 'profile'
        model = Profile
        fields = ['login', 'status']

Better yet, create some superclass for all your model serializers, assign the metaclass there, make all of your serializers inherit from that superclass which will then use the metaclass throughout.

1👍

Metaclasses are definitely the right answer unless your code can require python >= 3.6. Starting with 3.6 there is a new feature called the __init_subclass__ hook.

So you can do something like

class foo:

    @classmethod
    def __init_subclass__(cls, *args, **kwargs):
        Serializers.register_class(cls)

Whenever a child of Foo is defined, the __init_subclass__ method on Foo will be called, passing in the child class reference as cls.

Leave a comment