[Django] #25127: document how to define models in multiple modules

5 views
Skip to first unread message

Django

unread,
Jul 15, 2015, 1:27:29 PM7/15/15
to django-...@googlegroups.com
#25127: document how to define models in multiple modules
-------------------------------+--------------------
Reporter: keturn | Owner: nobody
Type: Uncategorized | Status: new
Component: Documentation | Version: 1.8
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------
Though recent versions of Django have taken steps to support the ability
have a number of models organized in a `models/` package instead of a
single `models.py` file, the Models documentation topic does not give
guidance on how to do this.

Searching the web for answers turns up a lot of 2009-era results, which I
believe are misleading when applied to current versions of Django.

There is a [https://code.djangoproject.com/wiki/CookBookSplitModelsToFiles
cookbook entry] which looks at least halfway current.

Statements I've seen (which I think are now questionable) are:

* If your models are not in `models.py`, you have to explicitly set
`db_table` on each model.
* ...you have to explicitly set `app_label` on each model
* in `models.py` or `models/__init__.py` you have to `import *` from each
module where you define models

There's this statement in the
[https://docs.djangoproject.com/en/1.7/releases/1.7/#app-loading-refactor
Django 1.7 release notes]:

> Application labels are assigned correctly to models even when they’re
defined outside of models.py. You don’t have to set app_label explicitly
any more.

which makes me think all of those things may be obsolete. Are there any
constraints on where you define models now? If they're not in `models.py`,
what do you need to do to ensure they're loaded?

Documentation on the
[https://docs.djangoproject.com/en/dev/ref/applications/#initialization-
process app initilaization process] still says the app's `models` module
or package is loaded, so maybe that "you must `import *` in your
`models.py` or `models/__init__.py`" thing is still true?

--
Ticket URL: <https://code.djangoproject.com/ticket/25127>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Jul 15, 2015, 1:34:45 PM7/15/15
to django-...@googlegroups.com
#25127: document how to define models in multiple modules
--------------------------------------+------------------------------------
Reporter: keturn | Owner: nobody
Type: Cleanup/optimization | Status: new
Component: Documentation | Version: 1.8
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------
Changes (by timgraham):

* needs_better_patch: => 0
* needs_docs: => 0
* type: Uncategorized => Cleanup/optimization
* needs_tests: => 0
* stage: Unreviewed => Accepted


Comment:

Yes, I believe that last statement is correct. For example, in Django's
own test suite:
https://github.com/django/django/blob/bbbb7ce115ac619255100cee6dccd32ed4346d98/tests/auth_tests/models/__init__.py

--
Ticket URL: <https://code.djangoproject.com/ticket/25127#comment:1>

Django

unread,
Jul 15, 2015, 2:47:21 PM7/15/15
to django-...@googlegroups.com
#25127: document how to define models in multiple modules
--------------------------------------+------------------------------------
Reporter: keturn | Owner: nobody
Type: Cleanup/optimization | Status: new
Component: Documentation | Version: 1.8

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------

Comment (by aaugustin):

Indeed, Django 1.7's app-loading process is good at figuring out which app
a given model belongs to, as long as you organize your code in a sensible
way. To be safe, you should ensure that importing `path.to.app.models` has
the side-effect of importing all models belonging to that app.

Not doing so will generally work in practice, but in theory it could lead
to inconsistencies in the app-cache registry. For instance, you may be
unable to query relations involving these models until they get imported,
perhaps by a later HTTP request. This could manifest as random errors in
production for a short time after restarting the server. You don't want to
face such issues.

Technically, you don't need to import the model classes themselves into
`path.to.app.models`. You just need to import the modules that defines
them so that the model classes get created in the memory of your Python
process, at which point they register themselves with the app registry.

However, it's a good idea to ensure that `from path.to.app.models import
WhateverModel` works for any model, because that's one of the most common
import patterns in Django projects. For this reason, I think we should
encourage always importing all models into the `models` package when
they're defined in submodules.

--
Ticket URL: <https://code.djangoproject.com/ticket/25127#comment:2>

Django

unread,
Jul 15, 2015, 3:06:52 PM7/15/15
to django-...@googlegroups.com
#25127: document how to define models in multiple modules
--------------------------------------+------------------------------------
Reporter: keturn | Owner: nobody
Type: Cleanup/optimization | Status: new
Component: Documentation | Version: 1.8

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------

Comment (by keturn):

Great, I think that's everything we need to know to document this.

That last point (about "always import all models into the models package")
sounds like a stylistic one I'm not yet sure I agree with, but given that
the modules do need to get imported in order for the classes to be
registered, having the documentation suggest a canonical place to do that
importing sounds like a good idea.

I guess the thing I want to get clear on is, if `from path.to.app.models
import WhateverModel` doesn't work, is that a choice that you can make
within your own project's organizational style, or is it something that
will actually break interactions with django core or common third-party
apps? I'm noticing there's an AppConfig.models_module. I'm not sure what
users of that actually do with it, but it sounds like a thing that would
break if you didn't follow that import convention.

--
Ticket URL: <https://code.djangoproject.com/ticket/25127#comment:3>

Django

unread,
Jun 3, 2016, 1:13:21 PM6/3/16
to django-...@googlegroups.com
#25127: document how to define models in multiple modules
--------------------------------------+------------------------------------
Reporter: keturn | Owner: palmerev
Type: Cleanup/optimization | Status: assigned
Component: Documentation | Version: 1.8

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------
Changes (by palmerev):

* status: new => assigned
* owner: nobody => palmerev


--
Ticket URL: <https://code.djangoproject.com/ticket/25127#comment:4>

Django

unread,
Jun 3, 2016, 4:13:14 PM6/3/16
to django-...@googlegroups.com
#25127: document how to define models in multiple modules
--------------------------------------+------------------------------------
Reporter: keturn | Owner: palmerev
Type: Cleanup/optimization | Status: assigned
Component: Documentation | Version: 1.8

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------
Changes (by timgraham):

* needs_better_patch: 0 => 1
* has_patch: 0 => 1


Comment:

[https://github.com/django/django/pull/6708 PR] with comments for
improvement.

--
Ticket URL: <https://code.djangoproject.com/ticket/25127#comment:5>

Django

unread,
Jun 3, 2016, 5:01:41 PM6/3/16
to django-...@googlegroups.com
#25127: document how to define models in multiple modules
--------------------------------------+------------------------------------
Reporter: keturn | Owner: palmerev
Type: Cleanup/optimization | Status: assigned
Component: Documentation | Version: 1.8

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------

Comment (by keturn):

> You can then import classes directly from the `models` module as you
normally would.

Yes, if you import them to `models/__init__.py`, you can import them
elsewhere as `.models.Robot`, but `.models.robot.Robot` also works if you
want to take advantage of that structure you created when you split things
out into multiple models files.

(which for `robot.Robot` sounds redundant but maybe `from
.models.synthetics import Robot, Android` would be useful.)

This is the part I feel most unsure about what to include in the
documentation, because one hand I think the "There Should Be One Obvious
Way To Do" it principle applies here, so it seems disadvantageous to go in
to a lot of "you could import it this way **or** this way **or**..."

On the other hand, I can also imagine myself coming to this and thinking,
"wait, if I have to import things as if they were in `myapp.models`
anyway, then doesn't that sort of defeat the purpose of splitting them
up?"

--
Ticket URL: <https://code.djangoproject.com/ticket/25127#comment:6>

Django

unread,
Jun 3, 2016, 5:41:17 PM6/3/16
to django-...@googlegroups.com
#25127: document how to define models in multiple modules
--------------------------------------+------------------------------------
Reporter: keturn | Owner: palmerev
Type: Cleanup/optimization | Status: assigned
Component: Documentation | Version: 1.8

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------

Comment (by timgraham):

You must import the models in `models/__init__.py` for Django to work
properly. As with normal Python, you can use either import path in your
own code.

--
Ticket URL: <https://code.djangoproject.com/ticket/25127#comment:7>

Django

unread,
Jun 4, 2016, 7:38:15 AM6/4/16
to django-...@googlegroups.com
#25127: document how to define models in multiple modules
--------------------------------------+------------------------------------
Reporter: keturn | Owner: palmerev
Type: Cleanup/optimization | Status: assigned
Component: Documentation | Version: 1.8

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------
Changes (by timgraham):

* needs_better_patch: 1 => 0


--
Ticket URL: <https://code.djangoproject.com/ticket/25127#comment:8>

Django

unread,
Jun 4, 2016, 11:48:13 AM6/4/16
to django-...@googlegroups.com
#25127: document how to define models in multiple modules
--------------------------------------+------------------------------------
Reporter: keturn | Owner: palmerev
Type: Cleanup/optimization | Status: closed
Component: Documentation | Version: 1.8
Severity: Normal | Resolution: fixed

Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------
Changes (by Tim Graham <timograham@…>):

* status: assigned => closed
* resolution: => fixed


Comment:

In [changeset:"84d8d1d7151a4ee70ae35037d37f76a40d18da64" 84d8d1d7]:
{{{
#!CommitTicketReference repository=""
revision="84d8d1d7151a4ee70ae35037d37f76a40d18da64"
Fixed #25127 -- Documented how to organize models in a package.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/25127#comment:9>

Django

unread,
Jun 4, 2016, 11:50:59 AM6/4/16
to django-...@googlegroups.com
#25127: document how to define models in multiple modules
--------------------------------------+------------------------------------
Reporter: keturn | Owner: palmerev
Type: Cleanup/optimization | Status: closed
Component: Documentation | Version: 1.8

Severity: Normal | Resolution: fixed
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------

Comment (by Tim Graham <timograham@…>):

In [changeset:"aa1bdc07a9f048e8b7b0734b41f879b4027742d9" aa1bdc07]:
{{{
#!CommitTicketReference repository=""
revision="aa1bdc07a9f048e8b7b0734b41f879b4027742d9"
[1.9.x] Fixed #25127 -- Documented how to organize models in a package.

Backport of 84d8d1d7151a4ee70ae35037d37f76a40d18da64 from master
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/25127#comment:10>

Django

unread,
Jun 4, 2016, 11:51:00 AM6/4/16
to django-...@googlegroups.com
#25127: document how to define models in multiple modules
--------------------------------------+------------------------------------
Reporter: keturn | Owner: palmerev
Type: Cleanup/optimization | Status: closed
Component: Documentation | Version: 1.8

Severity: Normal | Resolution: fixed
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------

Comment (by Tim Graham <timograham@…>):

In [changeset:"101f99977688530d5821c8129f626da68025d211" 101f999]:
{{{
#!CommitTicketReference repository=""
revision="101f99977688530d5821c8129f626da68025d211"
[1.10.x] Fixed #25127 -- Documented how to organize models in a package.

Backport of 84d8d1d7151a4ee70ae35037d37f76a40d18da64 from master
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/25127#comment:11>

Reply all
Reply to author
Forward
0 new messages