.NoReverseMatch: Reverse for 'author-detail' with arguments '('',)' not found. 1 pattern(s) tried: ['catalog/author/(?P
Many people have already asked similar questions to this, but I still cannot figure out the solution unfortunately. I am doing a Django tutorial from https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website . I compared my code with theirs on GitHub but I do not see any difference. The current state of my code is here https://github.com/diveki/webdev/tree/master/django_projects/locallibrary it works well except for showing the details of the Author model.
The error message I get is: django.urls.exceptions.NoReverseMatch: Reverse for 'author-detail' with arguments '('',)' not found. 1 pattern(s) tried: ['catalog/author/(?P<pk>[0-9]+)$']
.
The full error that django gives when I click on the Author list items:
NoReverseMatch at /catalog/author/1
Reverse for 'author-detail' with arguments '('',)' not found. 1 pattern(s) tried: ['catalog/author/(?P<pk>[0-9]+)$']
Request Method: GET
Request URL: http://127.0.0.1:8000/catalog/author/1
Django Version: 3.0.4
Exception Type: NoReverseMatch
Exception Value:
Reverse for 'author-detail' with arguments '('',)' not found. 1 pattern(s) tried: ['catalog/author/(?P<pk>[0-9]+)$']
Exception Location: C:\Users\divekizs\AppData\Local\Continuum\anaconda3\envs\django\lib\site-packages\django\urls\resolvers.py in _reverse_with_prefix, line 677
Python Executable: C:\Users\divekizs\AppData\Local\Continuum\anaconda3\envs\django\python.exe
Python Version: 3.7.3
Python Path:
['C:\\Users\\divekizs\\Python\\Scripts\\WebDev\\django_projects\\locallibrary',
'C:\\Users\\divekizs\\AppData\\Local\\Continuum\\anaconda3\\envs\\django\\python37.zip',
'C:\\Users\\divekizs\\AppData\\Local\\Continuum\\anaconda3\\envs\\django\\DLLs',
'C:\\Users\\divekizs\\AppData\\Local\\Continuum\\anaconda3\\envs\\django\\lib',
'C:\\Users\\divekizs\\AppData\\Local\\Continuum\\anaconda3\\envs\\django',
'C:\\Users\\divekizs\\AppData\\Local\\Continuum\\anaconda3\\envs\\django\\lib\\site-packages',
'C:\\Users\\divekizs\\AppData\\Local\\Continuum\\anaconda3\\envs\\django\\lib\\site-packages\\win32',
'C:\\Users\\divekizs\\AppData\\Local\\Continuum\\anaconda3\\envs\\django\\lib\\site-packages\\win32\\lib',
'C:\\Users\\divekizs\\AppData\\Local\\Continuum\\anaconda3\\envs\\django\\lib\\site-packages\\Pythonwin']
Server time: Wed, 18 Mar 2020 18:34:15 +0100
Traceback:
Environment:
Request Method: GET
Request URL: http://127.0.0.1:8000/catalog/author/1
Django Version: 3.0.4
Python Version: 3.7.3
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'catalog']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Template error:
In template C:\Users\divekizs\Python\Scripts\WebDev\django_projects\locallibrary\catalog\templates\base_generic.html, error at line 6
Reverse for 'author-detail' with arguments '('',)' not found. 1 pattern(s) tried: ['catalog/author/(?P<pk>[0-9]+)$']
1 : <!DOCTYPE html>
2 : <html lang="en">
3 : <head>
4 : {% block title %}<title>Local Library</title>{% endblock %}
5 : <meta charset="utf-8">
6 : <meta name="viewport" co ntent="width=device-width, initial-scale=1" >
7 : <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
8 : <!-- Add additional CSS in static file -->
9 : {% load static %}
10 : <link rel="stylesheet" href="{% static 'css/styles.css' %}">
11 : </head>
12 : <body>
13 : <div class="container-fluid">
14 : <div class="row">
15 : <div class="col-sm-2">
16 : {% block sidebar %}
Traceback (most recent call last):
File "C:\Users\divekizs\AppData\Local\Continuum\anaconda3\envs\django\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\divekizs\AppData\Local\Continuum\anaconda3\envs\django\lib\site-packages\django\core\handlers\base.py", line 145, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\divekizs\AppData\Local\Continuum\anaconda3\envs\django\lib\site-packages\django\core\handlers\base.py", line 143, in _get_response
response = response.render()
File "C:\Users\divekizs\AppData\Local\Continuum\anaconda3\envs\django\lib\site-packages\django\template\response.py", line 105, in render
self.content = self.rendered_content
File "C:\Users\divekizs\AppData\Local\Continuum\anaconda3\envs\django\lib\site-packages\django\template\response.py", line 83, in rendered_content
return template.render(context, self._request)
File "C:\Users\divekizs\AppData\Local\Continuum\anaconda3\envs\django\lib\site-packages\django\template\backends\django.py", line 61, in render
return self.template.render(context)
File "C:\Users\divekizs\AppData\Local\Continuum\anaconda3\envs\django\lib\site-packages\django\template\base.py", line 171, in render
return self._render(context)
File "C:\Users\divekizs\AppData\Local\Continuum\anaconda3\envs\django\lib\site-packages\django\template\base.py", line 163, in _render
return self.nodelist.render(context)
File "C:\Users\divekizs\AppData\Local\Continuum\anaconda3\envs\django\lib\site-packages\django\template\base.py", line 936, in render
bit = node.render_annotated(context)
File "C:\Users\divekizs\AppData\Local\Continuum\anaconda3\envs\django\lib\site-packages\django\template\base.py", line 903, in render_annotated
return self.render(context)
File "C:\Users\divekizs\AppData\Local\Continuum\anaconda3\envs\django\lib\site-packages\django\template\loader_tags.py", line 150, in render
return compiled_parent._render(context)
File "C:\Users\divekizs\AppData\Local\Continuum\anaconda3\envs\django\lib\site-packages\django\template\base.py", line 163, in _render
return self.nodelist.render(context)
File "C:\Users\divekizs\AppData\Local\Continuum\anaconda3\envs\django\lib\site-packages\django\template\base.py", line 936, in render
bit = node.render_annotated(context)
File "C:\Users\divekizs\AppData\Local\Continuum\anaconda3\envs\django\lib\site-packages\django\template\base.py", line 903, in render_annotated
return self.render(context)
File "C:\Users\divekizs\AppData\Local\Continuum\anaconda3\envs\django\lib\site-packages\django\template\loader_tags.py", line 62, in render
result = block.nodelist.render(context)
File "C:\Users\divekizs\AppData\Local\Continuum\anaconda3\envs\django\lib\site-packages\django\template\base.py", line 936, in render
bit = node.render_annotated(context)
File "C:\Users\divekizs\AppData\Local\Continuum\anaconda3\envs\django\lib\site-packages\django\template\base.py", line 903, in render_annotated
return self.render(context)
File "C:\Users\divekizs\AppData\Local\Continuum\anaconda3\envs\django\lib\site-packages\django\template\defaulttags.py", line 443, in render
url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
File "C:\Users\divekizs\AppData\Local\Continuum\anaconda3\envs\django\lib\site-packages\django\urls\base.py", line 87, in reverse
return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
File "C:\Users\divekizs\AppData\Local\Continuum\anaconda3\envs\django\lib\site-packages\django\urls\resolvers.py", line 677, in _reverse_with_prefix
raise NoReverseMatch(msg)
Exception Type: NoReverseMatch at /catalog/author/1
Exception Value: Reverse for 'author-detail' with arguments '('',)' not found. 1 pattern(s) tried: ['catalog/author/(?P<pk>[0-9]+)$']
I do not copy here all the code I wrote for this (unless you need it), but here is my models.py
, urls.py
from catalog
, the relevant code from views.py
and the templates:
Part of my catalog/models.py
:
from django.db import models
from django.urls import reverse # Used to generate URLs by reversing the URL patterns
import uuid # Required for unique book instances
class Author(models.Model):
"""Model representing an author."""
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
date_of_birth = models.DateField(null=True, blank=True)
date_of_death = models.DateField('died', null=True, blank=True)
class Meta:
ordering = ['last_name', 'first_name']
def get_absolute_url(self):
"""Returns the url to access a particular author instance."""
return reverse('author-detail', args=[str(self.id)])
def __str__(self):
"""String for representing the Model object."""
return '{0}, {1}'.format(self.last_name, self.first_name)
catalog/urls.py
:
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('books/', views.BookListView.as_view(), name='books'),
path('book/<int:pk>', views.BookDetailView.as_view(), name='book-detail'),
path('authors/', views.AuthorListView.as_view(), name='authors'),
path('author/<int:pk>',
views.AuthorDetailView.as_view(), name='author-detail'),
]
Complete catalog/views.py
:
from django.shortcuts import render
from catalog.models import Book, Author, BookInstance, Genre
from django.views import generic
# Create your views here.
def index(request):
num_books = Book.objects.all().count()
num_instances = BookInstance.objects.all().count()
#Available Books
num_instances_available = BookInstance.objects.filter(status__exact='a').count()
num_authors = Author.objects.count()
biography_num = Book.objects.filter(genre__name__icontains='horror').count()
context = {
'filtered': biography_num,
'title': 'Changed from index view',
'num_books': num_books,
'num_instances': num_instances,
'num_instances_available': num_instances_available,
'num_authors': num_authors,
}
return render(request, 'index.html', context=context)
class BookListView(generic.ListView):
model = Book
paginate_by = 5
# context_object_name = 'book_list'
# queryset = Book.objects.filter(title__icontains='zsolt')[:5]
#
class BookDetailView(generic.DetailView):
model = Book
# context_object_name = 'details'
# template_name = 'catalog/book_detail.html'
class AuthorListView(generic.ListView):
model = Author
paginate_by = 5
class AuthorDetailView(generic.DetailView):
model = Author
And finally here are the templates:
catalog/templates/base_generic.html
:
<!DOCTYPE html>
<html lang="en">
<head>
{% block title %}<title>Local Library</title>{% endblock %}
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<!-- Add additional CSS in static file -->
{% load static %}
<link rel="stylesheet" href="{% static 'css/styles.css' %}">
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-sm-2">
{% block sidebar %}
<ul class="sidebar-nav">
<li><a href="{% url 'index' %}">Home</a></li>
<li><a href="{% url 'books' %}">All books</a></li>
<li><a href="{% url 'authors' %}">All authors</a></li>
</ul>
{% endblock %}
</div>
<div class="col-sm-10 ">{% block content %}{% endblock %}
{% block pagination %}
{% if is_paginated %}
<div class="pagination">
<span class="page-links">
{% if page_obj.has_previous %}
<a href="{{ request.path }}?page={{ page_obj.previous_page_number }}">previous</a>
{% endif %}
<span class="page-current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
<a href="{{ request.path }}?page={{ page_obj.next_page_number }} ">next</a>
{% endif %}
</span>
</div>
{% endif %}
{% endblock %}
</div>
</div>
</div>
</body>
</html>
catalog/templates/catalog/book_details.html
:
{% extends "base_generic.html" %}
{% block content %}
<h1>Title: {{ book.title }}</h1>
<p><strong>Author:</strong> <a href="{% url 'author-detail' book.author.pk %}">{{ book.author }}</a></p> <!-- author detail link not yet defined -->
<p><strong>Summary:</strong> {{ book.summary }}</p>
<p><strong>ISBN:</strong> {{ book.isbn }}</p>
<p><strong>Language:</strong> {{ book.language }}</p>
<p><strong>Genre:</strong> {{ book.genre.all|join:", " }}</p>
<div style="margin-left:20px;margin-top:20px">
<h4>Copies</h4>
{% for copy in book.bookinstance_set.all %}
<hr>
<p class="{% if copy.status == 'a' %}text-success{% elif copy.status == 'm' %}text-danger{% else %}text-warning{% endif %}">
{{ copy.get_status_display }}
</p>
{% if copy.status != 'a' %}
<p><strong>Due to be returned:</strong> {{ copy.due_back }}</p>
{% endif %}
<p><strong>Imprint:</strong> {{ copy.imprint }}</p>
<p class="text-muted"><strong>Id:</strong> {{ copy.id }}</p>
{% endfor %}
</div>
{% endblock %}
catalog/templates/catalog/book_list.html
:
{% extends "base_generic.html" %}
{% block content %}
<h1>Book List</h1>
{% if book_list %}
<ul>
{% for book in book_list %}
<li>
<a href="{{ book.get_absolute_url }}">{{ book.title }}</a> ({{ book.author }}) {{ book.get_absolute_url }}
</li>
{% endfor %}
</ul>
{% else %}
<p>There are no books in the library.</p>
{% endif %}
{% endblock %}
catalog/templates/catalog/author_list.html
:
{% extends "base_generic.html" %}
{% block content %}
<h1>Author List</h1>
{% if author_list %}
<ul>
{% for author in author_list %}
<li>
<a href="{{ author.get_absolute_url }}">
{{ author }} ({{author.date_of_birth}} - {% if author.date_of_death %}{{author.date_of_death}}{% endif %})
</a>
</li>
{% endfor %}
</ul>
{% else %}
<p>There are no authors available.</p>
{% endif %}
{% endblock %}
catalog/templates/catalog/author_detail.html
:
{% extends "base_generic.html" %}
{% block content %}
hello
{% endblock %}
The problem is that author_detail.html
does not show up because django cannot reverse the 'author-detail'
name. I know that the {{ author.get_absolute_url }} gives the right url back. I did everything in the same way for the Book model and the
book_list.htmland
book_detail.html` works fine.
Could you please help me resolve the issue?
Answer
The error you're encountering, django.urls.exceptions.NoReverseMatch: Reverse for 'author-detail' with arguments '('',)' not found
, suggests that the URL reverse lookup for the author detail page is being passed an empty or invalid primary key (''
), which Django cannot resolve. Let's break down the issue and the possible fixes.
Issue Analysis
The line in your template book_details.html
that is causing the issue is:
<a href="{% url 'author-detail' book.author.pk %}">{{ book.author }}</a>
Here, you're trying to generate a URL for the author's detail page, passing book.author.pk
as an argument. However, if book.author.pk
is empty or not set correctly, Django will attempt to reverse the URL with an empty value, which leads to the NoReverseMatch
error.
Possible Causes & Fixes
-
Check if
book.author
isNone
or missing:- The error might be happening because
book.author
isNone
or missing for some of the books in the database. When you try to access.pk
on aNone
object, it will return an empty string. - You can add a check in the template to ensure that
book.author
exists before trying to generate the URL. Update your template like this:
<p><strong>Author:</strong> {% if book.author %} <a href="{% url 'author-detail' book.author.pk %}">{{ book.author }}</a> {% else %} Unknown Author {% endif %} </p>
This ensures that if
book.author
isNone
, it will display "Unknown Author" instead of attempting to generate a URL with an empty primary key. - The error might be happening because
-
Ensure that every
Book
has an associatedAuthor
:- Check that all
Book
instances in your database have a validAuthor
associated with them. If any books are missing an author, this could lead to the issue you're seeing. - You can check for missing authors by running a query in your Django shell:
from catalog.models import Book books_with_no_author = Book.objects.filter(author__isnull=True)
If any books are returned from this query, you need to ensure that all
Book
instances have an associatedAuthor
. - Check that all
-
Fix the
get_absolute_url
method inAuthor
model:- You've implemented
get_absolute_url
in theAuthor
model correctly. Just to verify, ensure that the URL pattern name'author-detail'
exists and matches the one used inurls.py
:
path('author/<int:pk>', views.AuthorDetailView.as_view(), name='author-detail'),
This path is correctly set up, so no changes are needed here. Just ensure the
author-detail
name matches everywhere it's used in templates. - You've implemented
Steps to Resolve
- Step 1: Add the conditional check in the
book_details.html
template to handle missing authors. - Step 2: Verify that all
Book
objects have an associatedAuthor
in the database. - Step 3: Ensure the
Author
model'sget_absolute_url
method is correctly implemented (which it seems to be).
Once you've made these changes, the error should be resolved, and the author detail page should work as expected.