@@ -299,18 +299,22 @@ def _get_declared_fields(cls, bases, attrs):
299
299
if isinstance (obj , Field )]
300
300
fields .sort (key = lambda x : x [1 ]._creation_counter )
301
301
302
- # If this class is subclassing another Serializer, add that Serializer's
303
- # fields. Note that we loop over the bases in *reverse*. This is necessary
304
- # in order to maintain the correct order of fields.
305
- for base in reversed (bases ):
306
- if hasattr (base , '_declared_fields' ):
307
- fields = [
308
- (field_name , obj ) for field_name , obj
309
- in base ._declared_fields .items ()
310
- if field_name not in attrs
311
- ] + fields
312
-
313
- return OrderedDict (fields )
302
+ # Ensures a base class field doesn't override cls attrs, and maintains
303
+ # field precedence when inheriting multiple parents. e.g. if there is a
304
+ # class C(A, B), and A and B both define 'field', use 'field' from A.
305
+ known = set (attrs )
306
+
307
+ def visit (name ):
308
+ known .add (name )
309
+ return name
310
+
311
+ base_fields = [
312
+ (visit (name ), f )
313
+ for base in bases if hasattr (base , '_declared_fields' )
314
+ for name , f in base ._declared_fields .items () if name not in known
315
+ ]
316
+
317
+ return OrderedDict (base_fields + fields )
314
318
315
319
def __new__ (cls , name , bases , attrs ):
316
320
attrs ['_declared_fields' ] = cls ._get_declared_fields (bases , attrs )
0 commit comments