#240 closed defect (fixed)
get_callback() improvements
| Reported by: | maurycy | Owned by: | Jacob |
|---|---|---|---|
| Component: | Core (Other) | Version: | |
| Severity: | trivial | Keywords: | |
| Cc: | Triage Stage: | Ready for checkin | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
The problem was:
[maurycy@localhost ~]$ grep -A 2 INSTALLED_APPS session/settings/main.py
INSTALLED_APPS = (
'session.apps.session',
)
[maurycy@localhost ~]$ cat session/settings/urls/main.py
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^session/', include('session.apps.session.urls.session')),
)
[maurycy@localhost ~]$ cat session/apps/session/urls/session.py
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^login/?$', 'session.apps.session.views.login'),
(r'^logout/?$', 'session.apps.session.views.logout'),
)
[maurycy@localhost ~]$ ls -1 session/apps/session/views/*.py
session/apps/session/views/__init__.py
session/apps/session/views/login.py
session/apps/session/views/logout.py
[maurycy@localhost ~]$ export DJANGO_SETTINGS_MODULE='session.settings.main'
[maurycy@localhost ~]$ django-admin.py runserver
Starting server on port 8000 with settings module 'session.settings.main'.
Go to http://127.0.0.1:8000/ for Django.
Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows).
[31/Jul/2005 00:32:03] "GET /session/login HTTP/1.1" 302 0
[31/Jul/2005 00:32:03] "GET /session/login/ HTTP/1.1" 500 883
Where http://localhost:8000/session/login returns the exception:
There's been an error:
Traceback (most recent call last):
File "/usr/lib/python2.4/site-packages/django/core/handlers/base.py", line 57, in get_response
callback, param_dict = resolver.resolve(path)
File "/usr/lib/python2.4/site-packages/django/core/urlresolvers.py", line 81, in resolve
match = pattern.search(app_path)
File "/usr/lib/python2.4/site-packages/django/core/urlresolvers.py", line 59, in search
sub_match = pattern.search(new_path)
File "/usr/lib/python2.4/site-packages/django/core/urlresolvers.py", line 34, in search
self.func = self.get_callback()
File "/usr/lib/python2.4/site-packages/django/core/urlresolvers.py", line 42, in get_callback
raise ViewDoesNotExist, "Tried %s. Error was: %s" % (self.callback, str(e))
ViewDoesNotExist: Tried session.apps.session.views.login. Error was: 'module' object has no attribute 'login'
Discussion:
05:30 < mmarshall> (r'^login/?$', 'session.apps.session.views.login.login')
05:31 < mmarshall> Try that.
05:31 < maurycypw> ugh?
05:31 < maurycypw> ugly, but works.
05:31 < mmarshall> hehe
05:31 < maurycypw> why it works?
05:31 -!- slightlyoff [~alex@12.180.45.190] has joined #django
05:32 < mmarshall> Django must need a function name.
05:32 < mmarshall> All you were giving it was a module name.
05:32 < maurycypw> eh. it should be fixed
05:32 < maurycypw> next ticket, please!
05:32 < mmarshall> I guess that the error was so unhelpful because it only
looked for attributes that were functions.
05:33 < mmarshall> In this case, you had an attribute named 'login', but it was
another module.
05:33 < mmarshall> And yes, it should be fixed :D
Change History (7)
comment:1 by , 20 years ago
| Resolution: | → invalid |
|---|---|
| Status: | new → closed |
comment:2 by , 20 years ago
| priority: | normal → low |
|---|---|
| Resolution: | invalid |
| Severity: | normal → trivial |
| Status: | closed → reopened |
The behavior is correct; the issue that maurycy had was that the error reported was confusing.
One possible solution, is for urlresolver to also check if the string given is a module (instead of just module+function.) If it is, try to get a function named 'default' from it. This results in a clearer error message. (and would have saved maurycy a fair amount of time.)
On the other hand, it might of been that he was up all night. :-/
Here is a patch to do this:
Index: django/core/urlresolvers.py
===================================================================
--- django/core/urlresolvers.py (revision 356)
+++ django/core/urlresolvers.py (working copy)
@@ -38,8 +38,14 @@
mod_name, func_name = get_mod_func(self.callback)
try:
return getattr(__import__(mod_name, '', '', ['']), func_name)
- except (ImportError, AttributeError), e:
+ except ImportError, e:
raise ViewDoesNotExist, "Tried %s. Error was: %s" % (self.callback, str(e))
+ except AttributeError, e:
+ try:
+ return getattr(__import__(self.callback,'','',['']),"default")
+ except (ImportError, AttributeError), e:
+ raise ViewDoesNotExist, "Tried %s. Error was: %s" % (self.callback, str(e))
+
class RegexURLMultiplePattern:
def __init__(self, regex, urlconf_module):
comment:3 by , 20 years ago
Exactly. Thanks, mmarshall. I was so sleepy to describe this problem in the more detailed manner.
By the way, would be also nice to try not "default", but the same name of attribute as module. For example, "login" for module "login".
comment:4 by , 20 years ago
| Owner: | changed from to |
|---|---|
| Status: | reopened → new |
Ah, I see. I'm less inclined to call a "default" function since that behavior would be non-obvious, but a better error message certainly is worth doing.
comment:5 by , 20 years ago
| Status: | new → assigned |
|---|
comment:6 by , 20 years ago
| Resolution: | → fixed |
|---|---|
| Status: | assigned → closed |
Um... I'm not entirely sure what's supposed to be fixed here; a view must be a callable, and you can't call a module.