While the code mentions that abstract models can not be instantiated [1],
I couldn't find mention of this in the docs. Abstract models without
foreign keys can still be instantiated perfectly fine.
I couldn't find any description of this change in the Release Notes, so
not sure if I missed it there or if this is maybe an undocumented
backwards-incompatible change.
--
Ticket URL: <https://code.djangoproject.com/ticket/26977>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* cc: charettes (added)
* needs_better_patch: => 0
* component: Uncategorized => Database layer (models, ORM)
* needs_tests: => 0
* needs_docs: => 0
* type: Cleanup/optimization => Bug
* stage: Unreviewed => Accepted
Comment:
I'm not sure about the correct resolution, but I bisected the change to
9239f1dda7b94f53d21efb8b5e4d056e24f4e906 and am attaching a reproduction
test case for Django's test suite.
--
Ticket URL: <https://code.djangoproject.com/ticket/26977#comment:1>
* Attachment "26977-test.diff" added.
* component: Database layer (models, ORM) => Documentation
* needs_docs: 0 => 1
* type: Bug => Cleanup/optimization
Comment:
While it's not explicitly mentioned abstract models are not instantiable
in the documentation there's a mention that
[https://docs.djangoproject.com/en/1.9/topics/db/models/#model-inheritance
such models are never meant to be used in isolation].
I would argue that even if it worked in Django < 1.8 it was undefined
behavior and this breakage shouldn't be considered as a break of backward
compatiblity. Even if we were to fix the `get_default()` case abstract
models with lazily defined relationships (by passing model names instead
of model classes) are now completely unusable as they're not resolved
anymore.
Since the issue can be worked around by avoiding lazily defined
relationships on abstract models and the reported use case was never meant
to be supported I suggest we amend the documentation to be more explicit.
--
Ticket URL: <https://code.djangoproject.com/ticket/26977#comment:2>
Comment (by timgraham):
How about raising a helpful message saying that abstract models can't be
instantiated?
--
Ticket URL: <https://code.djangoproject.com/ticket/26977#comment:3>
Comment (by charettes):
Replying to [comment:3 timgraham]:
> How about raising a helpful message saying that abstract models can't be
instantiated?
Raising a `TypeError` with an helpful message in Django 1.11+ could be
useful but I don't think it should be backported at this point.
--
Ticket URL: <https://code.djangoproject.com/ticket/26977#comment:4>
Comment (by Ien Cheng):
Wouldn't doing unit tests on a abstract model class be an appropriate use
case for instantiating an abstract class? If not, what is the recommended
approach to unit testing abstract model logic?
--
Ticket URL: <https://code.djangoproject.com/ticket/26977#comment:5>
* owner: nobody => Jacob Walls
* status: new => assigned
* has_patch: 0 => 1
* easy: 0 => 1
Comment:
[https://github.com/django/django/pull/13267 PR]
The documentation for Abstract base classes does mention that abstract
models cannot be instantiated, but it comes in the discussion of the
example `CommonInfo`. With the feedback provided by the `TypeError` raised
in this PR, my initial thought is that this is sufficient documentation.
If folks want the prohibition on instantiation moved earlier, up above the
example, it could be easily done.
--
Ticket URL: <https://code.djangoproject.com/ticket/26977#comment:6>
* needs_docs: 1 => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/26977#comment:7>
Comment (by Jacob Walls):
Thinking more on this, if folks decide to add extra documentation or move
documentation (that abstract models should not be instantiated) to a more
discoverable place, that is probably something to be considered for
backport, if it's worth doing at all. In that case that would be a
separate PR/ticket, no? The change in this PR won't be backported.
--
Ticket URL: <https://code.djangoproject.com/ticket/26977#comment:8>
Comment (by felixxm):
It's stated in docs that abstract models cannot be instantiated, IMO there
is no need for an extra clarification.
--
Ticket URL: <https://code.djangoproject.com/ticket/26977#comment:9>
* component: Documentation => Database layer (models, ORM)
* stage: Accepted => Ready for checkin
--
Ticket URL: <https://code.djangoproject.com/ticket/26977#comment:10>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"c7e7f176c13b1070c689feb5255c07b524933e12" c7e7f17]:
{{{
#!CommitTicketReference repository=""
revision="c7e7f176c13b1070c689feb5255c07b524933e12"
Fixed #26977 -- Made abstract models raise TypeError when instantiating.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/26977#comment:11>