I would like to declare som common fields in a mixin class, used by subclasses of both serializer.Serializer and serializer.ModelSerializer. These fields, however, seems not to be picked up, even though defined in Meta.fields. Is this by design?
Repro:
class TestSerializerMixin:
def test_mixin(self):
class MyMixin(object):
some_field = serializers.BooleanField()
class MySerializer(MyMixin, serializers.Serializer):
class Meta:
fields = ['some_field']
serializer = MySerializer(data={})
serializer.is_valid()
assert 'some_field' in serializer.errors
=>
assert 'some_field' in serializer.errors
E assert 'some_field' in {}
E + where {} = MySerializer(data={}):.errors
Fields are gathered on classes that inherit from serializers.
Your mixin has object as parent and thus break the field introspection.
Ok, see _declared_fields is populated in SerializerMetaclass. Would it be ok to use this class on the mixin to get the fields registered?
Should likely do the trick
It does:
class TestSerializerMixin:
def test_mixin(self):
@six.add_metaclass(serializers.SerializerMetaclass)
class MyMixin(object):
some_field = serializers.BooleanField()
class MySerializer(MyMixin, serializers.Serializer):
class Meta:
fields = ['some_field2']
serializer = MySerializer(data={})
serializer.is_valid()
assert 'some_field' in serializer.errors
I more asking if this from a framework design perspective is ok or if the meta class is considered internal.
The metaclass is considered as internal since it's not documented. However, it's unlikely to change.
Why do
@six.add_metaclass(serializers.SerializerMetaclass)
class MyMixin(object):
when you can just do
class MyMixin(serializers.Serializer):
especially since the former is not technically a public API? Is there something I'm missing? ModelSerializer inherits from Serializer.
I'm using this for both Serializer and ModelSerializer. Not sure about the consequences for multiple inheritance like that. Guess it should work if the mixin class is listed after the ModelSerializer
Using Serializer instead of just the meta may mess with heritage if some intermediate mixins do override some members.
I know one thing that could be problematic when inheriting serializers.Serializer is having to add definitions for all abstract methods of Serializer in said mixin. I used the metaclass and was successful in achieving what I wanted.
Most helpful comment
The metaclass is considered as internal since it's not documented. However, it's unlikely to change.