pythonregexdjangourlconf

Django Error passing URL argument from Template to View: NoReverseMatch Reverse not found. 1 pattern(s) tried


I am trying to pass configure a URL like so:

/details/12345

Template HTML:

    <div class="row">
    {% if article_list %}
    {% for article in article_list %}
    <div>
      <h2>{{ article.title }}</h2>
      <p>{{ article.body }}</p>
      <p><a class="btn btn-default" href="{% url 'details' article.id %}" role="button">View details &raquo;</a></p>
    </div><!--/.col-xs-6.col-lg-4-->
    {% endfor %}
    {% endif %}
  </div><!--/row-->

urls.py (full):

    from django.conf import settings
from django.conf.urls import include, url
from django.conf.urls.static import static
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^$', 'news_readr.views.home', name='home'),
    url(r'^details/(?P<article_id>\d+)/$', 'news_readr.views.details', name='details'),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

if settings.DEBUG:
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

views.py:

from django.shortcuts import render
from .models import Article

# Create your views here.
def home(request):
    title = "Home"
    article_list = Article.objects.all()
    for article in article_list:
        print(article.id)
    context = {
               "title": title,
               "article_list": article_list,
               }
    return render(request, "home.html", context)

def details(request, article_id = "1"):
    article = Article.objects.get(id=article_id)
    return render(request, "details.html", {'article': article})

I am getting an error that says:

 NoReverseMatch at /

Reverse for 'details' with arguments '()' and keyword arguments '{}'
not found. 1 pattern(s) tried: ['details/(?P<article_id>\\d+)/$']

I'm one week old at Django, and I think there's something wrong with my URL Named Group config. Please help! TIA!

Update: If I remove the URL config and change it back to:

url(r'^details/$', 'news_readr.views.details', name='details'),

The error changes to:

Reverse for 'details' with arguments '(1,)' and keyword arguments '{}' not found. 1 pattern(s) tried: ['details/$']

So it seems to be picking up the argument that is passed 1 in this case. So this seems to be an issue with the regular expression. I tried the expression out at Pythex, but even there, the expression doesn't seem to be matching anything.


Solution

  • For the url pattern

    url(r'^details/(?P<article_id>\d+)/$', 'news_readr.views.details', name='details'),
    

    The correct way to use the tag is

    {% url 'details' article.id %}
    

    This because the details url pattern has a group article_id, so you have to pass this to the tag.

    If you have the above url pattern, and {{ article.id}} displays correctly in the template, then the above template tag should not give the error Reverse for 'details' with arguments '()'. That suggests you have not updated the code, or you have not restarted the server after changing code.

    If you change the url pattern to

    url(r'^details/$', 'news_readr.views.details', name='details')
    

    then you need to remove the article.id from the url tag.

    {% url 'details' %}