Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inherited serializers #2418

Closed
fredericcambon opened this issue Jan 14, 2015 · 4 comments
Closed

Inherited serializers #2418

fredericcambon opened this issue Jan 14, 2015 · 4 comments

Comments

@fredericcambon
Copy link

We recently upgraded to DRF 3.0 and noticed an important change of behaviour with the serializers.

For performance reasons, we implemented serializers in DRF 2.X that inherited each other to stay as DRY as possible. For one type of model we sometimes have up to 5/6 sub serializers

class TestSerializer(serializers.ModelSerializer):
    a = serializers.SerializerMethodField('get_a')

    class Meta:
        model = TestModel
        fields = ['a', 'b', 'c']

    def get_a(self, obj):
        return 0


class TestSubSerializer(TestSerializer):
    class Meta:
        model = TestModel
        fields = ['a']

This is useful because we don't have to rewrite get_a for each subserializer.

However this does not work in 3.0 because the __new__,__init__ methods of SerializerMetaclass retrieve the declared_fields of the current serializer class, not of its parents.
The following classes (with real code obviously) throw this error :

ImproperlyConfigured: Field name 'a' is not valid for model ModelBase.

It does so because a = serializers.serializers.SerializerMethodField('get_a') is declared in the parent class

Perhaps we are doing something wrong and not using the serializers properly ?

Thank you for your answer

@tomchristie
Copy link
Member

Either related to, or duplicate of #2388 - haven't determined which yet.
In short tho - yes we should be supporting the inheritance case shown above so that's certainly something we'll prioritize getting fixed.

@tomchristie
Copy link
Member

Copied your example as a test case, but does not reproduce...

from rest_framework import serializers
from django.db import models

class TestModel(models.Model):
    b = models.IntegerField()
    c = models.IntegerField()

class TestSerializer(serializers.ModelSerializer):
    a = serializers.SerializerMethodField('get_a')

    class Meta:
        model = TestModel
        fields = ['a', 'b', 'c']

    def get_a(self, obj):
        return 0

class TestSubSerializer(TestSerializer):
    class Meta:
        model = TestModel
        fields = ['a']

def test_sub():
    TestSubSerializer()

Closing this off, but still continuing with the valid #2388.

Can reopen this is a failing test case is supplied as a pull request, or the question is otherwise clarified.
Perhaps this was an earlier issue that is now resolved in 3.0.3

@fredericcambon
Copy link
Author

#2388 is the same issue, the workaround provided solved my problem.

Thank you !

@tomchristie tomchristie removed this from the 3.0.4 Release milestone Jan 21, 2015
@aryabartar
Copy link

I came up with the exact same problem,
My DRF version is 3.9.4 but I can't inherit serializer fields in subclass and I have to redefine that field in each subclass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants