Reputation: 8765
If I import django's built in login view as in following code
from django.conf.urls import patterns, include, url
from django.contrib.auth.views import login
urlpatterns = patterns('',
url(r'login/$', login, name='login'),
)
every thing works fine, but if I'll include it in following way
from django.conf.urls import patterns, include, url
from django.contrib import auth
urlpatterns = patterns('',
url(r'login/$', auth.views.login, name='login'),
)
I get the following error
Exception Value: 'module' object has no attribute 'views'
what is really bothering me is in another project I am importing it the second way and it is working fine. Does anyone know what's going on over here?
Upvotes: 13
Views: 18963
Reputation: 2814
In the second project you've probably already imported the auth.views
module before calling auth.views.login
. Python stitches your imported modules when it can.
For example, this will work
>>> from django.contrib.auth.views import login #or from django.contrib.auth import views
>>> from django.contrib import auth
>>> auth.views.login
<function login at 0x02C37C30>
The first import doesn't even have to mention the login
view. This will also work.
>>> from django.contrib.auth.views import logout
...
#then import auth.views.login
The following won't because python does not know of the views
module since it isn't registered in auth.__init__.py
>>> from django.contrib import auth
>>> auth.views.login
...
AttributeError: 'module' object has no attribute 'views'
Upvotes: 13
Reputation: 342
In the first import (from django.contrib.auth.views import login
), the dot syntax is traversing the module hierarchy. In the urlpattern access (auth.views.login
), the dot-syntax is doing property (ie. class) lookup. From my shell_plus, you can see that "auth" doesn't have a views property.
In [1]: from django.contrib import auth
In [2]: auth.<TAB FOR COMPLETION>
auth.BACKEND_SESSION_KEY auth.load_backend
auth.ImproperlyConfigured auth.login
auth.PermissionDenied auth.logout
auth.REDIRECT_FIELD_NAME auth.models
auth.SESSION_KEY auth.re
auth.authenticate auth.rotate_token
auth.forms auth.settings
auth.get_backends auth.signals
auth.get_permission_codename auth.tokens
auth.get_user auth.user_logged_in
auth.get_user_model auth.user_logged_out
auth.hashers auth.user_login_failed
auth.import_by_path
This is why it's giving you an error. It really shouldn't work if you're trying that in another project/file either -- unless your other project's auth.__init__.py
is auto-loading its submodules.
Upvotes: 1