#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 , 19 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
comment:2 by , 19 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 , 19 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 , 19 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 , 19 years ago
Status: | new → assigned |
---|
comment:6 by , 19 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.