Skip to content

Commit

Permalink
Fix serializer multiple inheritance bug
Browse files Browse the repository at this point in the history
  • Loading branch information
rpkilby committed Oct 11, 2019
1 parent cf2442d commit 9984fa2
Showing 1 changed file with 16 additions and 12 deletions.
28 changes: 16 additions & 12 deletions rest_framework/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,18 +299,22 @@ def _get_declared_fields(cls, bases, attrs):
if isinstance(obj, Field)]
fields.sort(key=lambda x: x[1]._creation_counter)

# If this class is subclassing another Serializer, add that Serializer's
# fields. Note that we loop over the bases in *reverse*. This is necessary
# in order to maintain the correct order of fields.
for base in reversed(bases):
if hasattr(base, '_declared_fields'):
fields = [
(field_name, obj) for field_name, obj
in base._declared_fields.items()
if field_name not in attrs
] + fields

return OrderedDict(fields)
# Ensures a base class field doesn't override cls attrs, and maintains
# field precedence when inheriting multiple parents. e.g. if there is a
# class C(A, B), and A and B both define 'field', use 'field' from A.
known = set(attrs)

def visit(name):
known.add(name)
return name

base_fields = [
(visit(name), f)
for base in bases if hasattr(base, '_declared_fields')
for name, f in base._declared_fields.items() if name not in known
]

return OrderedDict(base_fields + fields)

def __new__(cls, name, bases, attrs):
attrs['_declared_fields'] = cls._get_declared_fields(bases, attrs)
Expand Down

0 comments on commit 9984fa2

Please sign in to comment.