Reputation: 8755
This happens in Django context, but the question is not Django specific.
I'm trying to split my big urls.py
into smaller and more manageable chunks (app includes, third-party modules, search, admin, development and so on). So instead of urls.py
, I'm using urls/
directory now, with urls/__init__.py
containing code like this:
import admin
urlpatterns += admin.urlpatterns
Now I've got into trouble with third-party modules. For example, I'm overriding a bunch of URLs and views for django-messages
, and so I've put all of it into urls/messages.py
. It turns out, I can't import django-messages
' views then, since
from messages.views import inbox
inside urls/messages.py
tries to import from local directory first, finds a messages
module, but can't import messages.views
then, since urls/messages/views.py
is obviously absent. I wouldn't like having to rename my modules to something like urls.messages_urls
, but I haven't found a way to explicitely tell Python to import the "other" messages.views
. Neither would I like to specify my imported views via strings, even though I can do that in Django.
How can I solve this situation cleanly?
Upvotes: 1
Views: 1059
Reputation: 11369
For those who could not find it, I was hitting ambiguous import errors. For example, in a django project, let's say I have this tree :
In init.py, I want to import tax.models.tax.Tax. So I write :
from tax.models.tax import Tax
But python does not find the correct import (it looks for models inside tax.models) and throws
ImportError: No module named models
You have indeed understood that it's all about relative imports. python first looks in the current module. If the first part of your import exists in the current module, it fails. This behaviour has been fixed in Python 2.5 (and may have become default in Python 3.0), you just have to add :
from __future__ import absolute_import
before your absolute imports. Have a look at Python 2.5 introduces absolute imports for more thorough information.
Upvotes: 2
Reputation: 599450
This is the wrong way to do it.
Django has a method for splitting urls.py into separate files, and that is to use include()
. Keep the urls for each application in its own urls.py, and include them into the main one.
Upvotes: 2
Reputation: 4849
Have you tried:
from django.contrib.messages.views import inbox
Untested, but I'd think the full import would work as expected.
Upvotes: 1