user2959896
user2959896

Reputation:

Can't get the url function to work with a specific syntax in django

I've visited the documenation at https://docs.djangoproject.com/en/1.6/ref/templates/builtins/#std:templatetag-url several times and i cant seem to get this syntax to work anywhere:

{% url 'view' obj.id %}

I have a view that takes one parameter so this should work but im only getting NoReverseMatch exception for some strange reason.

When doing it like this:

{% url 'view' obj.id as test %}
<a href="{{ test }}">test</a>

..im getting the correct url returned back and the link address displays correctly, but when using the above mentioned syntax without setting is as a variable it doesnt work, when i for example use it directly in an element.

When trying to do this which im trying to do:

{% url 'view' obj.id as test %}
<input type="hidden" value="{{ test }}">

im not getting any error but it doesnt seem like im getting any value in the value field because if there were a value in the field the code would do something, and when replacing the variable with a hard-coded string it does work.

When doing this:

{% url 'view' obj.id as test %}
{{ test }}

just to try to print the value it doesnt return anything which i find strange because when using it with the a element in html as shown at the first code line above it displays the correct url.

So basically, im only getting the {% url 'view' obj.id %} syntax to work with the a element of html and only if i define it as a variable.

I would like to use the {% url 'view' obj.id %} syntax in order to have a DRY code. According to the documenation this should work, does anyone have a clue about why this isnt working ? If you need more information then please let me know and i will update the question with the necessary information.

UPDATE: I'm currently using django 1.6. The typo in the second snippet has been corrected. The exact line from urls.py is (im at this page, using the comment system at /comment/ which should do a reverse to the display_story view (it works without problems when hardcoding the value attribute of the input html tag but not with the url function):

url(r'^story/display/(?P<specific_story>\d+)/$', 'base.views.display_story', name='display_story'),
url(r'^comments/', include("django.contrib.comments.urls"))

I have also tried the url function just on the application i have created without going through the comments application but i get the same problem.

This is the error message:

NoReverseMatch at /story/display/1/
Reverse for 'display_story' with arguments '(1,)' and keyword arguments '{}' not found.

Even though i know that the view exists and takes one argument.

This is the html code:

<input type="hidden" name="next" value="{% url 'display_story' story_details.id %}">

I have named views with the name argument and i apply the namespace when necessary.

The django docs says: exception NoReverseMatch The NoReverseMatch exception is raised by django.core.urlresolvers when a matching URL in your URLconf cannot be identified based on the parameters supplied.

but that doesnt seem to be the case.

This urls.py:

url(r'^story/display/(?P<specific_story>\d+)/$', 'base.views.display_story', name='display_story')

should match this view code:

def display_story(request, specific_story):
    """ Display details for a specific story. """
    story_details = Story.objects.get(id=specific_story)

    return render(request, "base/story/display_story.html", {
                    'story_details': story_details,
        })

but for some reason django doesnt think the parameter sent is the the one the function receives when it clearly is stated so in the code.

Update 2: When giving a keyword argument instead of a positional argument i get this error:

NoReverseMatch at /story/display/1/
Reverse for 'display_story' with arguments '()' and keyword arguments '{u'specific_story': 1}' not found.

This code is used:

{% url 'display_story' specific_story=story_details.id %}

Update 3: I will update the question with the values of the local vars for the reverse function.

To add some additional infor i ran some code in the python shell:

>>> import base.views
>>> from django.core.urlresolvers import reverse
>>>
>>> test=1
>>> reverse("display_story", kwargs={'test': test})
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Users/exceed/code/projects/python-2.7/lib/python2.7/site-packages/django/core/urlresolvers.py", line 496, in reverse
    return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
  File "/Users/exceed/code/projects/python-2.7/lib/python2.7/site-packages/django/core/urlresolvers.py", line 416, in _reverse_with_prefix
    "arguments '%s' not found." % (lookup_view_s, args, kwargs))
NoReverseMatch: Reverse for 'display_story' with arguments '()' and keyword arguments '{'test': 1}' not found.
>>>
>>>
>>> reverse("display_story", args=[1])
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Users/exceed/code/projects/python-2.7/lib/python2.7/site-packages/django/core/urlresolvers.py", line 496, in reverse
    return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
  File "/Users/exceed/code/projects/python-2.7/lib/python2.7/site-packages/django/core/urlresolvers.py", line 416, in _reverse_with_prefix
    "arguments '%s' not found." % (lookup_view_s, args, kwargs))
NoReverseMatch: Reverse for 'display_story' with arguments '(1,)' and keyword arguments '{}' not found.

Upvotes: 1

Views: 435

Answers (1)

BBT
BBT

Reputation: 461

Unless your view is named 'view' in the urlconf, you should use the full python dotted import path in the tag. For example:

{% url 'my_app.views.my_view' obj.id %}

If you want to test it properly, you can also use the django shell

python manage.py shell

and try the 'reverse' function:

from django.core.urlresolvers import reverse
reverse('my_app.views.my_view' args=[1])

>> '/my/awesome/url/1'

edit: also make sure that you didn't namespace your urls, if you did, you should include the namespace in the url tag:

{% url 'namespace:view' obj.id %}

another edit, because I have a feeling this might be it. I apologise for abusing the answer system instead of comments, but since I'm only starting out my reputation is too low.

Can you post the full urlconfig from your root urls.py up until the 'misbehaving' url? I have had cases where an url captured a group (say, an ID) and then included a bunch of other urls, leading to two required arguments for the reverse function.

Upvotes: 2

Related Questions