2

I had two methods create and update in the views, in which update takes one argument whereas create does not take any. I have decided to turn them into only one function update_create because they were not that different.

This is how the new method in views looks:

  def update_create(request, id=None):

This is my urls.py:

  url(r'^(\d+)/update/$|create/$', update_create, name='update_create'),

This is how my template looks in templates/list.html

  <a href="{% url 'update_create' %}"> Create a new event </a>

I got this error when using the above code:

  NoReverseMatch at /agenda/list/
  Reverse for 'update_create' with arguments '()' and keyword arguments '{}' not found.

But, if I use this in my templates instead (I have added an argument), it works without any errors:

  <a href="{% url 'update_create' 1 %}"> Create a new event </a>

Can someone explain what's happening? Why previous code didn't work, and Why the new code is working?

Bharadwaj Srigiriraju
  • 2,196
  • 4
  • 25
  • 45
smarber
  • 4,829
  • 7
  • 37
  • 78

2 Answers2

2

URL pattern (\d+) expects number to be provided as argument. To resolve the issue simply provide urls like this:

url(r'^(\d+)/update/$', update_create, name='update_create'),
url(r'^update/$', update_create, name='update_create'),
mariodev
  • 13,928
  • 3
  • 49
  • 61
  • Fixed, I just modify a bit my urls.py to make the argument optional: url(r'^(\d+)?/?update/$|create/$', update_create, name='update_create'), now it works. Thanks you :) – smarber Sep 27 '13 at 23:05
  • 2
    @smarber - I would recommend you taking mariodev's approach - Having two separate URLs to keep it explicit. This is more readable, and easy to debug. – karthikr Sep 27 '13 at 23:46
  • I was just trying to avoid verbosity as much as possible, but this shouldn't make debugging harder. I see what you mean, thanks for the advises – smarber Sep 28 '13 at 10:40
1

As mariodev pointed out, your url pattern was expecting a digit in front of the url. As such, your first url:

<a href="{% url 'update_create' %}"> Create a new event </a>

would generate a url like /update, which wasn't a valid url. However, the latter url:

<a href="{% url 'update_create' 1 %}"> Create a new event </a>

would generate a url like /1/update, which was a valid url.

From the django docs: https://docs.djangoproject.com/en/dev/topics/http/urls/

Basically subsequent arguments get parsed on first come first serve, and passed to your view. Another thing to consider when developing is using explicitly named parameters, as the django docs elaborate on.

james
  • 36
  • 3