Why recommend to include project name in settings?

58 views
Skip to first unread message

Chris Wilson

unread,
Feb 10, 2012, 7:36:27 AM2/10/12
to Django Developers
Hi all,

I'd like to inquire about the design decision to recommend users to
include the project name in DJANGO_SETTINGS_MODULE and ROOT_URLCONF, for
example:

> When using django-admin.py, you can either set the environment variable
> once, or explicitly pass in the settings module each time you run the
> utility...
>
> export DJANGO_SETTINGS_MODULE=mysite.settings

<https://docs.djangoproject.com/en/dev/topics/settings/>

> A string representing the full Python import path to your root URLconf.
> For example: "mydjangoapps.urls"

<https://docs.djangoproject.com/en/dev/ref/settings/#root-urlconf>

> But "mysite" is a package, and Django wants us to be able to import
> "mysite.settings" and "mysite.urls" (in fact, the latter is the default
> ROOT_URLCONF setting). In order to make that possible, setup_environ
> does some magic... This bit of clever causes a boat-load of problems...

<http://groups.google.com/group/django-developers/browse_frm/thread/44b70a37ff73298b>

My question is, why exactly Django wants us to be able to import
"mysite.settings" and "mysite.urls"? Wouldn't it be much simpler and
better if we could just import settings and urls?

As an experiment, I've removed the "setup_environ(settings_mod)" from my
manage.py, which adds the project's parent directory to the PYTHONPATH,
and it seems to work so far. I think that mod_wsgi uses an environment
without this addition as well, leading to tickets like this:

<https://code.djangoproject.com/ticket/15058>
<https://code.djangoproject.com/ticket/16673>

Is there any reason not to drop the project name part of
DJANGO_SETTINGS_MODULE and ROOT_URLCONF, to reduce the risk of confusion,
pollution, double imports and bad practice app coding in Django?

Cheers, Chris.
--
Aptivate | http://www.aptivate.org | Phone: +44 1223 760887
The Humanitarian Centre, Fenner's, Gresham Road, Cambridge CB1 2ES

Aptivate is a not-for-profit company registered in England and Wales
with company number 04980791.

Carl Meyer

unread,
Feb 10, 2012, 10:17:07 AM2/10/12
to django-d...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi Chris,

On 02/10/2012 05:36 AM, Chris Wilson wrote:
>> But "mysite" is a package, and Django wants us to be able to import
>> "mysite.settings" and "mysite.urls" (in fact, the latter is the
>> default ROOT_URLCONF setting). In order to make that possible,
>> setup_environ does some magic... This bit of clever causes a boat-load
>> of problems...
>
> <http://groups.google.com/group/django-developers/browse_frm/thread/44b70a37ff73298b>
>
>
> My question is, why exactly Django wants us to be able to import
> "mysite.settings" and "mysite.urls"? Wouldn't it be much simpler and
> better if we could just import settings and urls?
>
> As an experiment, I've removed the "setup_environ(settings_mod)" from my
> manage.py, which adds the project's parent directory to the PYTHONPATH,
> and it seems to work so far. I think that mod_wsgi uses an environment
> without this addition as well, leading to tickets like this:
>
> <https://code.djangoproject.com/ticket/15058>
> <https://code.djangoproject.com/ticket/16673>
>
> Is there any reason not to drop the project name part of
> DJANGO_SETTINGS_MODULE and ROOT_URLCONF, to reduce the risk of
> confusion, pollution, double imports and bad practice app coding in Django?

If you follow that quoted thread to the end, you'll find that this
problem has already been resolved in trunk :-) See
https://docs.djangoproject.com/en/dev/releases/1.4/#updated-default-project-layout-and-manage-py
for the release-notes summary.

For the default project layout, I chose to resolve it in favor of having
an outer "project package", as this namespaces the project better and
avoids potential top-level namespace clashes with generic names like
"settings" and "urls". However, it's easy enough to adjust the layout
and imports for your own project to eliminate that project package and
just use "import settings" and "import urls", if you prefer that.

Carl
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk81NPMACgkQ8W4rlRKtE2fulACfQRFyBOBEdB5slItKesanxCr0
lXoAoM4i5LFMn3L2DOYqqyyOr+6WJ6hL
=HWsX
-----END PGP SIGNATURE-----

Chris Wilson

unread,
Feb 10, 2012, 10:25:12 AM2/10/12
to django-d...@googlegroups.com
Hi Carl,

On Fri, 10 Feb 2012, Carl Meyer wrote:

>> Is there any reason not to drop the project name part of
>> DJANGO_SETTINGS_MODULE and ROOT_URLCONF, to reduce the risk of
>> confusion, pollution, double imports and bad practice app coding in
>> Django?
>
> If you follow that quoted thread to the end, you'll find that this
> problem has already been resolved in trunk :-) See
> https://docs.djangoproject.com/en/dev/releases/1.4/#updated-default-project-layout-and-manage-py
> for the release-notes summary.

Thanks, I had seen the patch on Trac and noticed that it was being
resolved in the direction of the "status quo", by enforcing the presence
of a top-level directory/module/package. This is the opposite of what I
was suggesting: entirely removing the top-level thing. I was curious about
the reasons for this decision, and whether the (apparently simpler)
alternative had been considered and rejected, and if so why?

> For the default project layout, I chose to resolve it in favor of having
> an outer "project package", as this namespaces the project better and
> avoids potential top-level namespace clashes with generic names like
> "settings" and "urls". However, it's easy enough to adjust the layout
> and imports for your own project to eliminate that project package and
> just use "import settings" and "import urls", if you prefer that.

Can you tell me more about why "potential top-level namespace clashes with
generic names like "settings" and "urls"" would be a problem?

We can always import .settings and .urls if we we want the top-level
modules, can't we?

Carl Meyer

unread,
Feb 10, 2012, 10:50:25 AM2/10/12
to django-d...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 02/10/2012 08:25 AM, Chris Wilson wrote:
> On Fri, 10 Feb 2012, Carl Meyer wrote:
>>> Is there any reason not to drop the project name part of
>>> DJANGO_SETTINGS_MODULE and ROOT_URLCONF, to reduce the risk of
>>> confusion, pollution, double imports and bad practice app coding in
>>> Django?
>>
>> If you follow that quoted thread to the end, you'll find that this
>> problem has already been resolved in trunk :-) See
>> https://docs.djangoproject.com/en/dev/releases/1.4/#updated-default-project-layout-and-manage-py
>> for the release-notes summary.
>
> Thanks, I had seen the patch on Trac and noticed that it was being
> resolved in the direction of the "status quo", by enforcing the presence
> of a top-level directory/module/package. This is the opposite of what I
> was suggesting: entirely removing the top-level thing. I was curious
> about the reasons for this decision, and whether the (apparently
> simpler) alternative had been considered and rejected, and if so why?

The status quo, as you noted, was "confusion, pollution, double imports
and bad practice app coding". Resolving this was the important step;
which direction it was resolved is a minor issue in comparison.

I did consider the alternative, but only briefly, as I think namespacing
is clearly better practice. In the lengthy django-developers thread
about the issue, nobody raised or advocated the non-namespaced option
(AFAIR).

>> For the default project layout, I chose to resolve it in favor of
>> having an outer "project package", as this namespaces the project
>> better and avoids potential top-level namespace clashes with generic
>> names like "settings" and "urls". However, it's easy enough to adjust
>> the layout and imports for your own project to eliminate that project
>> package and just use "import settings" and "import urls", if you
>> prefer that.
>
> Can you tell me more about why "potential top-level namespace clashes
> with generic names like "settings" and "urls"" would be a problem?

If things were set up in the way you are advocating, your Django
project's settings.py and urls.py would _be_ top-level modules, and they
would either mask or be masked by other top-level modules on sys.path
named "settings" or "urls", depending on sys.path ordering. Namespacing
the project is more explicit about what you are importing, and avoids
this possibility.

> We can always import .settings and .urls if we we want the top-level
> modules, can't we?

I can't figure out what you are suggesting here. "import .module" is not
legal syntax. "from . import module" is the opposite of importing a
top-level module; it's explicitly requesting a module relative to the
current package instead of a top-level module. In fact, if we followed
your suggestion and eliminated the project package, "from . import
settings" or "from . import urls" would be impossible; you can never
import top-level modules that way, Python will give you a "ValueError:
Attempted relative import in non-package."

Carl
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk81PMEACgkQ8W4rlRKtE2dgMACaAtfLhyjH4U3HBrotUtzg1FhO
cM0An2uKcQDpNsdz+89cROBOsRXeDwsY
=8K6l
-----END PGP SIGNATURE-----

Adam "Cezar" Jenkins

unread,
Feb 10, 2012, 10:47:13 AM2/10/12
to django-d...@googlegroups.com
On Fri, Feb 10, 2012 at 9:50 AM, Carl Meyer <ca...@oddbird.net> wrote:
"import .module"

Not arguing one way or another, but the above has always worked for me from a Python standpoint.

Carl Meyer

unread,
Feb 10, 2012, 10:57:39 AM2/10/12
to django-d...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Could you clarify what has worked for you about "import .module"? Every
way I try it, it's just a syntax error.

Carl
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk81PnMACgkQ8W4rlRKtE2c/OACfco31wdU7M3E40uIU7renmee7
CvQAoKWDiOAxJ2BuLiw1RcmsmdE6/Y5w
=MQVQ
-----END PGP SIGNATURE-----

Alex Gaynor

unread,
Feb 10, 2012, 10:52:22 AM2/10/12
to django-d...@googlegroups.com

--
You received this message because you are subscribed to the Google Groups "Django developers" group.
To post to this group, send email to django-d...@googlegroups.com.
To unsubscribe from this group, send email to django-develop...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.


I suspect you're going for `from . import module`?

Alex

--
"I disapprove of what you say, but I will defend to the death your right to say it." -- Evelyn Beatrice Hall (summarizing Voltaire)
"The people's good is the highest law." -- Cicero

Luke Granger-Brown

unread,
Feb 10, 2012, 10:58:04 AM2/10/12
to django-d...@googlegroups.com

It shouldn't work - the Python 2.7.2 documentation says that although you're allowed:
from relative_module import blah,

you have to use:
import module

Where module doesn't start with a . or consist solely of dots, but relative_module may.

Adam "Cezar" Jenkins

unread,
Feb 10, 2012, 12:52:49 PM2/10/12
to django-d...@googlegroups.com
You're right. Something similar "from .something import SomeThing". Like, https://github.com/django-nonrel/djangotoolbox/blob/develop/djangotoolbox/tests.py#L1
Reply all
Reply to author
Forward
0 new messages