views:

381

answers:

2

In my urls.py I have:

(r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/section/(?P<slug>[-\w]+)/$', 
    'paper.views.issue_section_detail', 
    {}, 
    'paper_issue_section_detail'
),

and I'm trying to do this in a template:

{% url paper_issue_section_detail issue.pub_date.year,issue.pub_date.month,issue.pub_date.day,section_li.slug %}

but I get this error:

TemplateSyntaxError
Caught an exception while rendering: Reverse for 'paper_issue_section_detail' with arguments '(2010, 1, 22, u'business')' and keyword arguments '{}' not found.

However, if I change the URL pattern to only require a single argument it works fine. ie:

(r'^(?P<year>\d{4})/$', 
    'paper.views.issue_section_detail', 
    {}, 
    'paper_issue_section_detail'
),

and:

{% url paper_issue_section_detail issue.pub_date.year %}

So it seems to complain when I pass more than a single argument using the 'url' template tag - I get the same error with two arguments. Is there a different way to pass several arguments? I've tried passing in named keyword arguments and that generates a similar error.

For what it's worth, the related view starts like this:

def issue_section_detail(request, year, month, day, slug):

How do I pass more than a single argument to the url template tag?

+3  A: 

Your month expression is (?P<month>\d{2}), but you're sending it the argument 1. The 1 doesn't match \d{2}, so the url resolver isn't finding your view.

Try changing the month expression to \d{1,2} (or something to that effect).

Seth
Thanks a lot for your suggestion Seth - I hadn't made the connection between the regexp and what I was trying to pass to it. But I didn't want to loosen the restriction on the URL, so I'm now changing the format of what I pass in, using Gregor Müllegger's suggestion.
Phil Gyford
+1  A: 

The problem lives in the /(?P<month>\d{2})/ part of your url configuration. It only allows exactly two digits (\d{2}) while issue.pub_date.month is only one digit.

You can do either allow also one digit in the URL (but this will violate the principle of unique URLs, /2010/1/... would be the same as /2010/01/...) or pass two digits to the month argument in your url templatetag.
You can use the date filter to achieve a consistent formating of date objects. Use the url tag like this:

{% url paper_issue_section_detail issue.pub_date|date:"Y",issue.pub_date|date:"m",issue.pub_date|date:"d",section_li.slug %}

Look at the month and day argument: It will be always displayed as two digits (with a leading zero if necessary). Have a look at the documentation of the now tag to see which options are possible for the date filter.

Gregor Müllegger
That sounds great - I don't really want to have change the possible formatting for the URL. But when I do issue.pub_date.month|date:"m" then an empty string gets passed to the URL/view.
Phil Gyford
You're right - I'm sorry. I obviously had it wrong in the original post. I corrected the `url` tag. You must use `issue.pub_date|date:"m"` instead of `issue.pub_date.month|date:"m"`. The `date` filter operates on `datetime` objects (the pub_date attribute) and not on integers (the pub_date.month attribute).
Gregor Müllegger
Doh, of course, I should have spotted that too. Thanks loads for the help Gregor.
Phil Gyford