Fixed #28198 -- Prevented model attributes from overriding deferred fields.#9126
Fixed #28198 -- Prevented model attributes from overriding deferred fields.#9126denys-tarykin wants to merge 1 commit intodjango:masterfrom
Conversation
|
Hi. Can you help me with checking of my pull request? Most of tests are failed. But in the logs I see that unit tests are was not started because of jgit exception |
|
If you amend your commit and push it to the branch, it should trigger the build again. You'll need to add a regression test anyway. |
|
How will this affect methods in subclassed models? For example, if |
|
This fix is not affect to methods and override only fields. Regarding your example, it possible to execute method of parent class in overridden method of child model |
|
any updates on this? who can decide if we accept it? |
ryanhiebert
left a comment
There was a problem hiding this comment.
LGTM. The example issue I mentioned on the ticket looks to be resolved, and the test seems to be a sufficient coverage to avoid regression.
|
Is there a committer willing to look at this patch? The tests pass, the bug is fixed, and a regression test is added. Thanks! |
timgraham
left a comment
There was a problem hiding this comment.
Please squash commits when updating and try to follow the commit message format.
django/db/models/base.py
Outdated
There was a problem hiding this comment.
We generally try to describe the issue sufficient so that a ticket reference isn't needed.
django/db/models/base.py
Outdated
There was a problem hiding this comment.
The comment needs improvement. I don't know what "duplicate public attributes" means.
django/db/models/base.py
Outdated
There was a problem hiding this comment.
Use hanging indent as described in Python coding style.
django/db/models/base.py
Outdated
There was a problem hiding this comment.
This condition could use a comment with an explanation. '__' might be replaced with LOOKUP_SEP if that's what it's checking.
There was a problem hiding this comment.
isn't it checking for name mangling and/or dunder methods?
django/db/models/base.py
Outdated
There was a problem hiding this comment.
Again, the comment isn't really clear to me.
tests/defer/tests.py
Outdated
There was a problem hiding this comment.
Use assertIs(..., False) to check for boolean attributes.
tests/defer/tests.py
Outdated
There was a problem hiding this comment.
I think a docstring would be useful to explain the expected behavior. See Python coding style for docstring guidelines.
django/db/models/base.py
Outdated
There was a problem hiding this comment.
if attr_per_parent: is simpler -- does the current implementation have an advantage over that? (It looks like it requires more computation.) Same comment below.
tests/defer/models.py
Outdated
There was a problem hiding this comment.
I think you could edit some existing models rather than adding three new models. We try to avoid adding new models since it decreases the runtime of the tests.
tests/defer/tests.py
Outdated
There was a problem hiding this comment.
I'm not sure that a separate test class is needed.
django/db/models/base.py
Outdated
django/db/models/base.py
Outdated
There was a problem hiding this comment.
no line continuations, instead use parentheses, see https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/coding-style/
docs/releases/1.11.7.txt
Outdated
There was a problem hiding this comment.
it looks like you've merged too much stuff into this branch. you probably want to rebase on top of master, rather than merge. use git rebase --interactive to select only your commits when you do so, to avoid pulling in these other changes.
0cb453a to
3a9e5c2
Compare
|
I've updated my commit. But I did not update tests models. Because any changes in existing models will affect on existing test, and in this case my commit will contains updates which are not related to issue |
|
@denys-tarykin : It looks like there are a couple comments, even without the model changes requested, that have not been addressed. Would you like some assistance addressing those? If so I might be able to make a PR to your branch. |
3a9e5c2 to
1cfe955
Compare
from parent classes Implemented logic that update the model creating process. The bases in `super_new(cls, name, bases, new_attrs)` can contain the implementation for a attributes which also provided in 'new_attrs'.Before model creating this implementations are removing from parent classes. This fix is necessary because during defer reading of field the result object will not contain implementation from parent class
1cfe955 to
307a82f
Compare
|
I've updated the code that is related to your comments |
carltongibson
left a comment
There was a problem hiding this comment.
I'm not, as yet, convinced by this.
The root cause of the issue here comes from Field.contribute_to_class():
django/django/db/models/fields/__init__.py
Lines 699 to 703 in a87189f
It would be nice to address it there, rather than in ModelBase.__new__().
If we're going to remove and then replace attributes on parent classes,
we need tests to ensure that logic is correct.
I suggest extracting two methods, or helper functions, to encapsulate the logic
in the two added blocks.
Each of these can then have test cases demonstrating the expected behaviour, and
that it's correct. The two can also be tested together to demonstrate that the
replacement always works as expected.
In general, rather than actually removing/replacing attributes, could we merely
generate a list that could be checked against in Field.contribute_to_class()?
carltongibson
left a comment
There was a problem hiding this comment.
I'm going to close this in favor of pursuing the fix in Field.contribute_to_class() that's being worked on in #11337.
IMO, only if a fix there is unavailable should we consider anything along these lines in ModelBase.__new__().
Thanks for the effort @denys-tarykin.
Attributes from parent classes will not overload attributes in child classes. During model creation process, attributes which are dublicated in parent and child classes will be removed. That attributes will restored for all parent classes after model creation process