NoReverseMatch:无法将参数从模板传递到视图。

时间:2017-08-31 03:57:12

标签: django django-templates django-views django-urls

我正在尝试在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验证了正则表达式是否有效。

如果我转到网址:http://localhost:8000/results/herald,我会得到正确的结果。

我错过了什么?

1 个答案:

答案 0 :(得分: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">

请注意,从现在开始,您的网址将采用以下格式:

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

<强>更新

如果您确实想要在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'))
    ...