Reputation: 4380
From my template:
<a href="{% url 'tracker:othermonth' year next_month %}">July</a>
URL Pattern:
url(r'^ocal/$', views.calendar, name = "othermonth"),
View:
def calendar(request, year, month):
my_year = int(year)
my_month = int(month)
my_calendar_from_month = datetime(my_year, my_month, 1)
my_calendar_to_month = datetime(my_year, my_month, monthrange(my_year, my_month)[1])
my_tickets = Event.objects.filter(on_sale__gte=my_calendar_from_month).filter(on_sale__lte=my_calendar_to_month)
my_previous_year = my_year
my_previous_month = my_month - 1
if my_previous_month == 0:
my_previous_year = my_year - 1
my_previous_month = 12
my_next_year = my_year
my_next_month = my_month + 1
if my_next_month == 13:
my_next_year = my_year + 1
my_next_month = 1
my_year_after_this = my_year + 1
my_year_before_this = my_year - 1
cal = TicketCalendar(my_tickets).formatmonth(year, month)
return render_to_response('calendar.html', {'events_list': my_tickets,
'calendar': mark_safe(cal),
'month': my_month,
'month_name': named_month(my_month),
'year': my_year,
'previous_month': my_previous_month,
'previous_month_name': named_month(my_previous_month),
'previous_year': my_previous_year,
'next_month': my_next_month,
'next_month_name': named_month(my_next_month),
'next_year': my_next_year,
'year_before_this': my_year_before_this,
'year_after_this': my_year_after_this,
}, context_instance=RequestContext(request))
Error:
Reverse for 'othermonth' with arguments '(2013, 7)' and keyword arguments '{}' not found.
I've searched through stackoverflow and the django documentation but I can't seem to figure out why I'm getting this NoReverseMatch
error. I'm sure its a very simple oversight on my part because I'm staring at code from a previous project which is almost identical to this and that works fine. Any help would be appreciated, thanks.
UPDATE: I tried removing the parameters that I was trying to send with the URL and that fixed the NoReverseMatch
however the view that is called requires those arguments so the link fails.
Upvotes: 5
Views: 5818
Reputation: 12144
Large context volumes caused this behavior for me as well, despite having the correct syntax.
I had this, on Django 1.5:
urls.py
url(r'(?P<CLASSID>[A-Z0-9_]+)/$', 'psclassdefn.views.psclassdefn_detail', name="psclassdefn_detail"),
template.html
{% for inst in li_inst %}
<li><a href={% url 'psclassdefn.views.psclassdefn_detail' CLASSID=inst.CLASSID %}></a></li>
{% endfor %}
I kept on getting NoReverseMatch even though the syntax seemed OK and I could reverse into a no-argument url.
Now, li_inst was a huge list of about 1000 rows fetched from the db and passed to the context variable. Just to test, I trimmed the list by removing all but 10 or so rows. And it worked, without any syntax changes.
Maybe the templating system intentionally throttles the context size? I can filter the list if needed, just didn't expect this error to come from it.
Upvotes: 1
Reputation: 37319
How do you plan for those arguments to be embedded in your URL? There's nothing capturing them, and no way for the reverse lookup to construct it. You need a URL pattern that accepts these parameters. Something like:
url(r'^ocal/(?P<year>\d{4})/(?P<month>(0|1)?\d)/$', views.calendar, name = "othermonth_bymonth"),
Using keyword rather than positional arguments here is optional, but I think it makes things easier - and allows setting default values that can trigger behavior like showing a calendar for the current day when nothing's specified.
Also, your mytickets
queryset can also be constructed thus:
mytickets = Event.objects.filter(on_sale__year=year, onsale__month=month)
Which I think is a little cleaner to read.
Actually, upon a closer look - Django's built in date based views can do a lot of this for you. If you haven't already looked into them, I recommend doing so:
https://docs.djangoproject.com/en/dev/ref/class-based-views/generic-date-based/
For this particular view, all you'd need to do is subclass MonthArchiveView
to create your TicketCalendar
instance and add it to your context.
Edit: OK, you're still getting problems. This is how I would go about solving this:
views.py
class TicketMonthArchiveView(MonthArchiveView):
allow_empty = True # show months even in which no tickets exist
allow_future = True # show future months
model = Event
def get_context_data(self, **kwargs):
base_context = super(TicketMonthArchiveView, self).get_context_data(**kwargs)
my_tickets = kwargs['object_list']
base_context['calendar'] = mark_safe(TicketCalendar(my_tickets).formatmonth(self.get_year(), self.get_month()))
# the above could be a little off because I don't know exactly how your formatmonth method works
return base_context
urls.py
from somewhere.views import TicketMonthArchiveView
# other patterns, plus:
url(r'^ocal/(?P<year>\d{4})/(?P<month>(0|1)?\d)/$', TicketMonthArchiveView.as_view(), name='calendar_by_month'),
template event_archive_month.html
<a href="{% url 'tracker:calendar_by_month' next_month|date:'%Y' next_month|date:'%m' %}">{{ next_month|date:'%f' }}</a>
Obviously there's a lot more you could do here with the year and day views, but this should demonstrate the general concepts.
Upvotes: 6