django rest framework abstract class serializer

后端 未结 4 977
名媛妹妹
名媛妹妹 2021-02-07 05:01

I have some models like these:

class TypeBase(models.Model):
    name = models.CharField(max_length=20)
    class Meta:
        abstract=True

class PersonType(T         


        
4条回答
  •  悲哀的现实
    2021-02-07 05:30

    As already mentioned in Sebastian Wozny's answer, you can't use a ModelSerializer with an abstract base model.

    Also, there is nothing such as an abstract Serializer, as some other answers have suggested. So setting abstract = True on the Meta class of a serializer will not work.

    However you need not use use a ModelSerializer as your base/parent serializer. You can use a Serializer and then take advantage of Django's multiple inheritance. Here is how it works:

    class TypeBaseSerializer(serializers.Serializer):
        # Need to re-declare fields since this is not a ModelSerializer
        name = serializers.CharField()
        id = serializers.CharField()
    
        class Meta:
            fields = ['id', 'name']
    
        def someFunction(self):
            #... will be available on child classes ...
            pass
    
    class PersonTypeSerializer(TypeBaseSerializer, serializers.ModelSerializer):
    
        class Meta:
            model = PersonType
            fields = TypeBaseSerializer.Meta.fields + ['another_field']
    
    
    class CompanyTypeSerializer(TypeBaseSerializer, serializers.ModelSerializer):
    
        class Meta:
            model = CompanyType
            fields = TypeBaseSerializer.Meta.fields + ['some_other_field']
    

    So now since the fields name and id are declared on the parent class (TypeBaseSerializer), they will be available on PersonTypeSerializer and since this is a child class of ModelSerializer those fields will be populated from the model instance.

    You can also use SerializerMethodField on the TypeBaseSerializer, even though it is not a ModelSerializer.

    class TypeBaseSerializer(serializers.Serializer):
        # you will have to re-declare fields here since this is not a ModelSerializer
        name = serializers.CharField()
        id = serializers.CharField()
        other_field = serializers.SerializerMethodField()
    
        class Meta:
            fields = ['id', 'name', 'other_field']
    
        def get_other_field(self, instance):
            # will be available on child classes, which are children of ModelSerializers
            return instance.other_field
    

提交回复
热议问题