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'))
...