Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using reverse() in django forms

I'm trying to use django's reverse() function in definition of django form for my custom widget, but am getting an error:

ImproperlyConfigured
The included urlconf urls doesn't have any patterns in it

Here is the code:

class WorkForm(forms.Form):
    # ...
    category = forms.ChoiceField(
        required=True,
        label=_('Category'),
        help_text=_('Select most appropriate category for your work.')
    )
    subcategory = forms.ChoiceField(
        widget=DependantChoiceWidget(
            default_value=_('Select category first'),
            data_source_url=reverse('works-json-categories'),
            # data_source_url='', -- it works this way
            depends_on='category_id'
        ),
        required=True,
        label=_('SubCategory'),
        help_text=_('Which subcategory suits your work best.')
    )

I am pretty sure, that my 'works.urls' is configured properly, since all other pages work as expected.

Is there a reason, why I cannot use reverse() in form definition? Does it have something to do with when this code runs? Is there a way to fix this, or the only choice here is to hardcode the URL?

Here is full error dump:

Environment:

Request Method: GET
Request URL: http://127.0.0.1:8000/works/add?category=1&subcategory=1

Django Version: 1.4 pre-alpha
Python Version: 2.7.1
Installed Applications:
['django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.admin',
 'django.contrib.admindocs',
 'social_auth',
 'sorl.thumbnail',
 'helpers',
 'users',
 'works',
 'debug_toolbar']
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.transaction.TransactionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'debug_toolbar.middleware.DebugToolbarMiddleware')


Traceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
  89.                     response = middleware_method(request)
File "/usr/local/lib/python2.7/dist-packages/django/middleware/common.py" in process_request
  67.             if (not _is_valid_path(request.path_info, urlconf) and
File "/usr/local/lib/python2.7/dist-packages/django/middleware/common.py" in _is_valid_path
  164.         urlresolvers.resolve(path, urlconf)
File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py" in resolve
  416.     return get_resolver(urlconf).resolve(path)
File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py" in resolve
  298.             for pattern in self.url_patterns:
File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py" in url_patterns
  328.         patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py" in urlconf_module
  323.             self._urlconf_module = import_module(self.urlconf_name)
File "/usr/local/lib/python2.7/dist-packages/django/utils/importlib.py" in import_module
  35.     __import__(name)
File "/var/www/megenius/trunk/urls.py" in <module>
  27.     url(r'^works/', include('works.urls')),
File "/usr/local/lib/python2.7/dist-packages/django/conf/urls/__init__.py" in include
  24.         urlconf_module = import_module(urlconf_module)
File "/usr/local/lib/python2.7/dist-packages/django/utils/importlib.py" in import_module
  35.     __import__(name)
File "/var/www/megenius/trunk/works/urls.py" in <module>
  2. from works.views import *
File "/var/www/megenius/trunk/works/views.py" in <module>
  9. from works.forms import WorkForm
File "/var/www/megenius/trunk/works/forms.py" in <module>
  10. class WorkForm(forms.Form):
File "/var/www/megenius/trunk/works/forms.py" in WorkForm
  31.             data_source_url=reverse('works-json-categories'),
File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py" in reverse
  473.                       (prefix, resolver.reverse(view, *args, **kwargs)))
File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py" in reverse
  360.         possibilities = self.reverse_dict.getlist(lookup_view)
File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py" in reverse_dict
  276.             self._populate()
File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py" in _populate
  242.         for pattern in reversed(self.url_patterns):
File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py" in url_patterns
  332.             raise ImproperlyConfigured("The included urlconf %s doesn't have any patterns in it" % self.urlconf_name)

Exception Type: ImproperlyConfigured at /works/add
Exception Value: The included urlconf urls doesn't have any patterns in it
like image 906
Silver Light Avatar asked Sep 15 '11 12:09

Silver Light


People also ask

What does reverse () do in Django?

the reverse function allows to retrieve url details from url's.py file through the name value provided there. This is the major use of reverse function in Django. The redirect variable is the variable here which will have the reversed value. So the reversed url value will be placed here.

What is reverse and reverse lazy in Django?

Reverse_lazy is, as the name implies, a lazy implementation of the reverse URL resolver. Unlike the traditional reverse function, reverse_lazy won't execute until the value is needed. It is useful because it prevent Reverse Not Found exceptions when working with URLs that may not be immediately known.

What does it mean to reverse a URL?

Just in case you do not know why it is called reverse : It takes an input of a url name and gives the actual url, which is reverse to having a url first and then give it a name.

How do I get an absolute URL in Django?

Use handy request. build_absolute_uri() method on request, pass it the relative url and it'll give you full one. By default, the absolute URL for request. get_full_path() is returned, but you can pass it a relative URL as the first argument to convert it to an absolute URL.


1 Answers

The problem might be that the form is defined before the urls have been loaded.

Django 1.4 will have a reverse_lazy feature that would solve this problem. You could implement it in your project yourself (see changeset 16121).

Alternatively, you could set the widget in your forms __init__ method instead. Then the reverse call happens when the form is created, after the urls have loaded.

class WorkForm(forms.Form):
    # ...
    subcategory = forms.ChoiceField(
        required=True,
        label=_('SubCategory'),
        help_text=_('Which subcategory suits your work best.')
    )
    def __init__(self, *args, **kwargs):
        super(WorkForm, self).__init__(*args, **kwargs)
        self.fields['subcategory'].widget=DependantChoiceWidget(
            default_value=_('Select category first'),
            data_source_url=reverse('works-json-categories'),
            depends_on='category_id'
        ),
like image 113
Alasdair Avatar answered Oct 04 '22 21:10

Alasdair