How can I import a specific module with an ambiguous name?
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/
dir开发者_Go百科ectory 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?
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.
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 :
- tax module
- models module
- init.py
- tax.py
- foo.py
- models module
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.
Have you tried:
from django.contrib.messages.views import inbox
Untested, but I'd think the full import would work as expected.
精彩评论