Skip to content

Binding child should happen in bind no init #5304

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

Closed
wants to merge 2 commits into from
Closed

Binding child should happen in bind no init #5304

wants to merge 2 commits into from

Conversation

sassanh
Copy link
Contributor

@sassanh sassanh commented Aug 3, 2017

Note: Before submitting this pull request, please review our contributing guidelines.

Description

It should fix several issues related to child caching wrong root, the one I was dealing with was that child of a many=True serializer didn't have access to context.

It should fix several issues related to child caching wrong root, the one I was dealing with was that child of a `many=True` serializer didn't have access to context.
@rpkilby
Copy link
Member

rpkilby commented Aug 3, 2017

Hi @sassanh. A test case demonstrating the described issue would be helpful.

  • It shows that there is indeed a bug that needs to be fixed.
  • It prevents future changes from accidentally reintroducing this bug.

@sassanh
Copy link
Contributor Author

sassanh commented Aug 3, 2017

@rpkilby sure, I'm currently out of time but I'll add a test asap. I saw some hacks introduced in stackoverflow to pass context to child of ListSerializer. This bug + those stackoverflow posts leads people to complicated code. It would be great if we merge it first and create another issue assigned to me to add test in future as I think I won't have free time in near future. Or maybe someone can write the test now. I was thinking about adding a test_context.py that tests all the expected behavior of context passing mechanism.

@sassanh
Copy link
Contributor Author

sassanh commented Aug 4, 2017

Actually if you don't access .root or things that use it internally like .context before binding is done I think there's no problem the way it is (without this patch). But if you call .context in init or call it in .to_internal_value (only when it's a child of a ListSerializer) it caches root before parent list is bound. Maybe we should reset the cache on certain events. For example I can change this PR to clear .root cache of self and all children when binding is done so that they update themselves when their root has a parent.

@xordoquy
Copy link
Collaborator

xordoquy commented Aug 4, 2017

It should fix several issues related to child caching wrong root, the one I was dealing with was that child of a many=True serializer didn't have access to context.

That looks suspicious to me. I can't double check but I'm pretty sure this part is already working fine.
Do you have any test case to highlight the issue ?

@sassanh
Copy link
Contributor Author

sassanh commented Aug 4, 2017

@rpkilby @xordoquy I added a test case that demonstrates how children can cache wrong root. It doesn't only happen if you access self.root in __init__, it also happens if you access it in update() of a child of a ListSerializer. But I guess even caching wrong root in __init__ enough to show there's a problem. I think either we should get rid of this cache (it doesn't bring a noticeable performance gain.) or unvalidate it when binding occurs.

@rpkilby
Copy link
Member

rpkilby commented Aug 7, 2017

btw - I haven't thoroughly read the referenced issue. That said, this is making me think of #5087. @sassanh are the two related?

Also, thanks for the added test.

@sassanh
Copy link
Contributor Author

sassanh commented Aug 7, 2017

@rpkilby Yeah the problem is the same, but the way to produce it is not by binding a field manually like it's described there so your suggestions about overriding get_fields doesn't work here. In the test I added I reproduced it with manually accessing .root in constructor of the child serializer but I usually avoid doing so (even though it's not documented that we should avoid accessing .root and .context and things that trigger caching root in constructor).

the main problem I dealt with in real life was that even though I didn't access .root nor .context there was a situation for ListSerializer and writing customized update method where using drf's api it accessed root internally and ruined the cache itself internally.

So I think we should either invalidate cache when needed or revert #3288 as it doesn't introduce any performance benefits as you said in the other thread:

Seems reasonable - the caching is just a couple of attribute accesses. I don't think there will be a tangible performance difference.

@rpkilby
Copy link
Member

rpkilby commented Aug 7, 2017

Hi @sassanh - closing this in favor of #5313

@rpkilby rpkilby closed this Aug 7, 2017
@sassanh
Copy link
Contributor Author

sassanh commented Aug 7, 2017

Thanks

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

Successfully merging this pull request may close these issues.

3 participants