-
-
Notifications
You must be signed in to change notification settings - Fork 6.9k
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
Fix serializer multiple inheritance bug #6980
Fix serializer multiple inheritance bug #6980
Conversation
Lets just make sure we triple check this before changing the behaviour here. |
I have some doubt about how it'll behave if we define a field in the grand parent and override it in a parent. |
Scratch my previous comment, it seems correct already. |
OK, so it's just exactly what we say in a release note... "...set |
@carltongibson that would apply to |
- Test declared filter ordering - Test multiple inheritance
9984fa2
to
6d84cb7
Compare
I added a test for declarative field ordering. The original version of the PR did break this, but the current version respects both mro and the field ordering. |
Nice. Good effort @rpkilby. I'm going to have to sit down with a coffee over the weekend and make sure I'm 100% clear on why this works. 😀 |
This is a bit longwinded, but as additional context.. let's use: class Base(serializers.Serializer):
f1 = serializers.CharField()
f2 = serializers.CharField()
class A(Base):
f3 = serializers.CharField()
class B(serializers.Serializer):
f3 = serializers.CharField()
f4 = serializers.CharField()
class TestSerializer(A, B):
f2 = serializers.CharField()
f5 = serializers.CharField() Of note,
And if you process the fields by mro, you would actually get:
Instead, the As to the existing implementation, it made sense to process the bases in reverse order and prepend, since the childmost fields have alread been resolved. Effectively, the code builds fields as: fields = [f2, f5] # TestSerializer
fields = [f3, f4, f2, f5] # B, TestSerializer
fields = [f1, f2, f3, f3, f4, f2, f5] # A, B, TestSerializer However, there's no reason to process in reverse order. The bases could have been collected in forwards order, and the The existing implementation is mostly correct. When the fields are collapsed into the ordered dict, the correct order is maintained, and the * although processed in reverse order, the base fields are prepended, placing For the first PR implementation, I effectively unreversed the processing of the bases, so fields = [f2, f5] # TestSerializer
fields = [f2, f5, f3, f4] # TestSerializer, B
fields = [f2, f5, f3, f4, f3, f1, f2] # TestSerializer, B, A This had the opposite effect of the above. While As to the current PR implementation, fields = [f2, f5] # TestSerializer
fields = [f1, f2, f3] + [f2, f5] # A + TestSerializer
fields = [f1, f2, f3, f4] + [f2, f5] # A, B + TestSerializer The result is similar to the existing implementation, however the I guess the best way of explaining the PR is that there are two changes:
|
Neato bit of fixing, that. |
* Expand declared filtering tests - Test declared filter ordering - Test multiple inheritance * Fix serializer multiple inheritance bug * Improve field order test to check for field types
* Expand declared filtering tests - Test declared filter ordering - Test multiple inheritance * Fix serializer multiple inheritance bug * Improve field order test to check for field types
Fixes #5798. As pointed out by @svilendobrev, the current code reverses the field order twice, defeating the point of reversing the first place. Thanks to @mwhansen for providing a minimal test case.
Note that I ran the test locally to verify the failure. Also, even though this is a relatively minor bugfix, I'm adding to the 3.11 milestone since it's technically a change in behavior to the public API.