Проблема при выполнении поиска с несколькими результатами. NoReverseMatch

Я делаю веб-приложение, которое использует API OpenLibrary, используя Django. В нем я выполняю поиск в API, если в результатах отображается более одной книги, я получаю такую ошибку:

NoReverseMatch at /search-results/

Отзыв для 'book_detail' с аргументами '('reina-roja-red-queen', 'Reina Roja / Red Queen')' не найден. Проверено 1 шаблон(ов): ['books/((?P[-a-zA-Z0-9_]+)/(?P[^/]+)+)']</p> </blockquote> <p> Мои файлы выглядят следующим образом:</p> <p>urls.py</p> <pre><code>from django.urls import path from . import views urlpatterns = [ path("", views.index, name="index"), path("search-results/", views.search_results, name="search_results"), path("books/<slug:slug>/<str:title>", views.book_detail, name="book_detail"), ] </code></pre> <p>views.py</p> <pre><code>from django.shortcuts import render, get_object_or_404, redirect from django.utils.text import slugify from books.api_library import search_book_by_author, search_book_by_title from .models import Book import requests import json def index(request): """ Index page """ if request.method == "POST": type_search = request.POST.get("type_search") search = request.POST.get("search") if type_search == "title": books_data = search_book_by_title(search).get("docs", []) elif type_search == "author": books_data = search_book_by_author(search).get("docs", []) if not books_data: books_data = [] request.session['search_results'] = books_data return redirect('search_results') return render(request, "books/index.html") def search_results(request): """ View to display search results """ search_results = request.session.get('search_results', []) books = [] for book in search_results: slug = slugify(book.get("title", "")) book_info = { "title": book.get("title", ""), "author": book.get("author_name", ""), "isbn": book.get("isbn", ""), "cover": book.get("cover", ""), "publisher": book.get("publisher", ""), "cover_url": f"https://covers.openlibrary.org/b/id/{book.get('cover_i', '')}-S.jpg", "description": book.get("description", ""), "publish_date": book.get("publish_date", ""), "slug": slug } books.append(book_info) return render(request, "books/search_results.html", {"books": books}) def book_detail(request, slug, title): """ Detail page """ print(title) url = f"https://openlibrary.org/search.json?title={title}" response = requests.get(url) book_data = response.json() print(book_data) for book in book_data: context = { "title": book.get("title", ""), "author": book.get("author_name", ""), "isbn": book.get("isbn", ""), "cover": book.get("cover", ""), "publisher": book.get("publisher", ""), "cover_url": f"https://covers.openlibrary.org/b/id/{book.get('cover_i', '')}-L.jpg", "description": book.get("description", ""), "publish_date": book.get("publish_date", ""), } return render(request, "books/book_detail.html", context) </code></pre> <p>index.html</p> <pre class="lang-html prettyprint-override"><code>{% extends "base.html" %} {% block content %} <form method="post"> {% csrf_token %} <article class="main__article search"> <fieldset class="search__fieldset"> <p class="search__p"> <label for="search" class="search__label">Search</label> <select name="type_search" id="type_search"> <option value="title">Title</option> <option value="author">Author</option> </select> <input type="text" name="search" id="search" class="search__input"> <button type="submit" class="search__button">Search</button> </p> </article> </form> <br> <article class="card"> {% for book in books %} <figure class="card__figure"> <img src="{{ book.cover_url }}" class="card__img", alt="{{ book.title }}", height="200", width="200"> </figure> <div class="card__div"> <h2 class="card__h2">{{ book.title }}</h2> <p class="card__p">Author: {{ book.author }}</p> <p class="card__p">Publish date: {{ book.publish_date }}</p> <p class="card__p">Publisher: {{ book.publisher }}</p> <a href="{% url 'book_detail' book.slug book.isbn %}" class="card__a" title="{{ book.title }}'}">View More</a> </div> {% endfor %} </article> {% endblock %} </code></pre> <p>search_results.html</p> <pre class="lang-html prettyprint-override"><code>{% extends "base.html" %} {% block content %} <h1>Search Results</h1> {% if books %} <ul> {% for book in books %} <li> <a href="{% url 'book_detail' book.slug book.title %}">{{ book.title }}</a> by {{ book.author }} </li> {% endfor %} </ul> {% else %} <p>No results found.</p> {% endif %} {% endblock %} </code></pre> <p>book_detail.html</p> <pre class="lang-html prettyprint-override"><code>{% extends "base.html" %} {% block content %} <article class="book-details"> <h1>{{ title }}</h1> <p><strong>Author(s):</strong> {{ author }}</p> {% if cover_url %} <img src="{{ cover_url }}" alt="Book Cover"> {% endif %} <p><strong>Description:</strong> {{ description }}</p> <!-- Otros detalles del libro que desees mostrar --> </article> {% endblock %} </code></pre> <p> Я хочу, чтобы мне показывали все результаты и я мог выбрать книгу и посмотреть в book_detail.html данные о ней.</p> <div class="index"> <div class="index__ad"> <!-- Yandex.RTB R-A-395615-4 --> <div id="yandex_rtb_R-A-395615-4" class="ads__text"> <div class="ads__text__content"></div> </div> <script>window.yaContextCb.push(()=>{ Ya.Context.AdvManager.render({ renderTo: 'yandex_rtb_R-A-395615-4', blockId: 'R-A-395615-4', }) })</script> </div> </div> <div class="df-feeds__entry__answer"> <p>Ваш второй параметр содержит косую черту, <code><str:…></code> этого не позволяет <code><path:…></code>, следует использовать конвертер путей:</p> <pre><code>path('books/<slug:slug>/<b><path:title></b>', views.book_detail, name='book_detail'),</code></pre> <p> При этом вы передаете заголовок с пробелами, косыми чертами и т. д. Это часто не очень хорошая идея, особенно в отношении <em> оптимизации поисковых систем (SEO)</em>.</p> </div> <a href="#top" class="backtotop"><i class="icon icon-chevron-up"></i> Вернуться на верх</a> </div> </div> <div class="main__sidebar"> <div role="sidebar"> <div class="main__sidebar__item"> <h4>Последние вопросы и ответы</h4> <p><a href="/qa/448100/">Is this djoser implementation secure?</a></p> <p><a href="/qa/448101/">Data not saved to database</a></p> <p><a href="/qa/448099/">Django Allauth's Google Login Redirect and Page Design</a></p> <p><a href="/qa/448098/">Access request session data of DetailView in CreateView in django</a></p> <p><a href="/qa/448097/">Export command not found in working django import-export app</a></p> <p><a href="/qa/448096/">Django: Unable to login into a account</a></p> <p><a href="/qa/448094/">SAP Connection failed: name 'Connection' is not defined, PYRFC in django</a></p> <p><a href="/qa/448095/">How to configure Nginx to serve Django and a Wordpress site on a specific route?</a></p> <p><a href="/qa/448093/">Failed to start gunicorn.socket: Unit gunicorn.socket has a bad unit file setting [closed]</a></p> <p><a href="/qa/448092/">How to create a Django custom field with different representations in admin, database, and Python code?</a></p> </div> <div class="main__sidebar__ad"> <!-- Yandex.RTB R-A-395615-3 --> <div id="yandex_rtb_R-A-395615-3" class="ads__sidebar"> <div style="height: 42vh;"></div> </div> <script>window.yaContextCb.push(()=>{ Ya.Context.AdvManager.render({ renderTo: 'yandex_rtb_R-A-395615-3', blockId: 'R-A-395615-3' }) })</script> </div> <div class="main__sidebar__item"> <h4>Рекомендуемые записи по теме</h4> <p><a href="/articles/tutorials/osnovy-biblioteki-python-mock-object/">Основы библиотеки Python Mock Object</a></p> <p><a href="/articles/tutorials/ispolzovanie-pyinstaller-dlya-legkogo-rasprostraneniya-prilozhenij-na-python/">Использование PyInstaller для легкого распространения приложений на Python</a></p> <p><a href="/articles/tutorials/refaktoring-prilozhenij-na-python-dlya-uprosheniya/">Рефакторинг приложений на Python для упрощения</a></p> <p><a href="/articles/python/raspoznavanie-lic-s-pomoshyu-python/">Распознавание лиц с помощью Python</a></p> <p><a href="/articles/python/chtenie-i-zapis-fajlov-v-python/">Чтение и запись файлов в Python</a></p> <p><a href="/articles/tutorials/povyshenie-effektivnosti-klassov-python-s-pomoshyu-super/">Повышение эффективности классов Python с помощью super()</a></p> <p><a href="/articles/python/pattern-fabrika-i-ego-realizaciya-v-python/">Паттерн Фабрика и его реализация в Python</a></p> <p><a href="/articles/python/razrabotka-na-python-v-visual-studio-code/">Разработка на Python в Visual Studio Code</a></p> <p><a href="/articles/python/asinhronnyj-vvod-vyvod-v-python/">Асинхронный ввод-вывод в Python</a></p> <p><a href="/articles/python/proverka-tipov-v-python/">Проверка типов в Python</a></p> </div> </div> </div> </div> </div> <footer class="footer"> <div class="footer__wrapper"> <p>© Django.Fun 2017-2023 | Django.Fun не связан с Django Software Foundation. Django - зарегистрированная торговая марка Django Software Foundation.</p> </div> </footer> <div id="version-switcher"> </div> <script src="/static/CACHE/js/output.9d9e6a0d5c41.js"></script> <!-- Yandex.Metrika counter --> <script type="text/javascript" > (function (d, w, c) { (w[c] = w[c] || []).push(function() { try { w.yaCounter46974723 = new Ya.Metrika({ id:46974723, clickmap:true, trackLinks:true, accurateTrackBounce:true, webvisor:true }); } catch(e) { } }); var n = d.getElementsByTagName("script")[0], s = d.createElement("script"), f = function () { n.parentNode.insertBefore(s, n); }; s.type = "text/javascript"; s.async = true; s.src = "https://mc.yandex.ru/metrika/watch.js"; if (w.opera == "[object Opera]") { d.addEventListener("DOMContentLoaded", f, false); } else { f(); } })(document, window, "yandex_metrika_callbacks"); </script> <noscript><div><img src="https://mc.yandex.ru/watch/46974723" style="position:absolute; left:-9999px;" alt="" /></div></noscript> <!-- /Yandex.Metrika counter --> </body> </html>