NoReverseMatch: невозможно передать параметр из шаблона для просмотра.

Я пытаюсь создать простую форму поиска в Django. Вот что у меня так далеко:

форма:

<form action="{% url 'search_pub' pub_name=pub_name %}" method="get">
    Publication name: <input type="text" id="pub_name" name="pub_name" value="herald">
    <input type="submit" value="Search">
</form>

urls.py

url(r'^search/$', views.search, name='search'),
url(r'^results/(?P<pub_name>[\w]+)/$', views.search_pub, name='search_pub'),

views.py

def search(request):
    return render(request, 'urlapp/search.html')

def search_pub(request, pub_name):
    pubs = Publication.objects.all().filter(title__icontains=pub_name)
    return render(request, 'app/results.html', {
        'publications': pubs
    })

models.py

class Publication(models.Model):
    title = models.CharField(max_length=30)

Я получаю следующую ошибку при открытии страницы поиска по адресу http://localhost:8000/search/:

NoReverseMatch at /search/
Reverse for 'search_pub' with keyword arguments '{'pub_name': ''}' not found. 1 pattern(s) tried: ['results/(?P<pub_name>[\\w]+)/$']

Я проверил, что регулярное выражение действует на сайте pythex.

Если я перейду к URL: http://localhost:8000/results/herald, я получу правильные результаты.

Что мне не хватает?

1 ответ

Решение

Вы не можете использовать переменные GET, как будто они являются аргументами URL. Кроме того, {% url ... значения вычисляются на стороне сервера, поэтому вы не можете динамически изменять их в форме HTML. Я бы сделал следующее:

Сначала измените следующую строку

url(r'^results/(?P<pub_name>[\w]+)/$', views.search_pub, name='search_pub'),

в

url(r'^results/$', views.search_pub, name='search_pub'),

Затем измените код представления так, чтобы он выглядел следующим образом:

def search_pub(request):                    # Remove pub_name from method signature
    pub_name = request.GET.get('pub_name')  # ...and fetch it from GET dict instead
    ...

Наконец, измените form тег:

<form action="{% url 'search_pub' %}" method="get">

Обратите внимание, что теперь ваши URL-адреса будут иметь следующую форму:

http://localhost:8000/results?pub_name=herald

Обновить:

Если вы действительно хотите иметь значение в URL, вы можете перенаправить с одного на другое:

Держите оба URL в вашем urls.py с разными именами:

url(r'^results/(?P<pub_name>[\w]+)/$', views.search_pub, name='search_pub_clean'),
url(r'^results/$', views.search_pub, name='search_pub'),

и код вида:

from django.shortcuts import redirect
def search_pub(request, pub_name=None):
    if pub_name is None:
        return redirect('search_pub_clean', pub_name=request.GET.get('pub_name'))
    ...
Другие вопросы по тегам