Django HTML POST 参数导致 NoReverseMatch
Posted
技术标签:
【中文标题】Django HTML POST 参数导致 NoReverseMatch【英文标题】:Django HTML POST parameters causes NoReverseMatch 【发布时间】:2017-05-14 15:45:15 【问题描述】:我有一个带有两个下拉列表的 html 帖子,我想将这些列表中选定的 Country
发送到 views.py
中的 search()
方法,然后将我发送到 results
视图。每当我添加 government
和 location
作为 html POST 操作的参数或在搜索正则表达式中添加它们的值时,我尝试这个我从我的 index
页面得到一个 NoReverseMatch
:
未找到带有参数“(”,“”)和关键字参数“”的“搜索”。尝试了 1 种模式:['search/(?P[A-Z]3)/(?P[A-Z]3)/']
我不会因为我做错了什么而导致这个错误。 (见代码中的cmets)
应用名称/views.py:
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect, HttpResponse
from .models import Country, Embassy
from django.template import loader
from django.urls import reverse
def index(request):
country = Country.objects.filter()
template = loader.get_template('appname/index.html')
context = 'countries': country
return render(request, 'appname/index.html', context)
def results(request, government, location):
return HttpResponse("Here are the Embassies sent by %s, located in %s." % (government, location))
def search(request):
countries = Country.objects.all()
form = request.POST
if request.method == 'POST':
try:
selected_government = get_object_or_404(pk=request.POST['government'])
except (KeyError, Country.DoesNotExist):
return render(request, 'appname/index.html',
'error_message': "You didn't select a government.",
)
try:
selected_location = get_object_or_404(pk=request.POST['location'])
except (KeyError, Country.DoesNotExist):
return render(request, 'appname/index.html',
'error_message': "You didn't select a location.",
)
else:
return HttpResponseRedirect(reverse('appname:results', args=(selected_government.code,selected_location.code,)))
应用名称/模板/应用名称/index.html:
% if error_message %<p><strong> error_message </strong></p>% endif %
# government and location in the form action causes a NoReverse Match
<form action="% url 'appname:search' government location %" method="POST">
% csrf_token %
<label>Find Embassies sent by</label>
<select name="government">
% for entry in countries %
<option value=" entry.code "> entry.name </option>
% endfor %
</select>
<label>that are located in</label>
<select name="location">
% for entry in countries %
<option value=" entry.code "> entry.name </option>
% endfor %
</select>
<input type="submit" value="Search" />
</form>
urls.py:
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^', include('appname.urls')),
url(r'^appname/', include('appname.urls')),
url(r'^admin/', admin.site.urls),
]
应用名称/urls.py:
from django.conf.urls import url
from . import views
app_name = 'appname'
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^(?P<embassy_id>[0-9]+)/$', views.embassy_info, name='embassy_info'),
url(r'^(?P<code>[A-Z]3)/$', views.country_info, name='country_info'),
url(r'^find/(?P<government>[A-Z]3)/(?P<location>[A-Z]3)/$', views.results, name='results'),
# the government and location values in search regex also cause a NoReverse Match
url(r'^search/(?P<government>[A-Z]3)/(?P<location>[A-Z]3)/', views.search, name='search'),
]
应用名称/models.py:
from django.db import models
class Country(models.Model):
code = models.CharField(primary_key=True, max_length=3)
name = models.CharField(max_length=50, db_column="Name")
def __str__(self):
return self.name
class Meta:
verbose_name = 'Country'
verbose_name_plural = 'Countries'
class Embassy(models.Model):
government = models.ForeignKey(Country, on_delete=models.CASCADE, related_name="government")
location = models.ForeignKey(Country, on_delete=models.CASCADE, related_name="location")
name = models.CharField(max_length=200, db_column="Name")
street_address = models.CharField(max_length=200, db_column="Address")
city = models.CharField(max_length=50, db_column="City")
phone_number = models.IntegerField(default=-1, db_column="Phone Number")
fax_number = models.IntegerField(null=True, blank=True, db_column="Fax Number")
email_address = models.CharField(max_length=200, db_column="Email")
website = models.CharField(max_length=200, db_column="Link")
def __str__(self):
return self.name
class Meta:
verbose_name = 'Embassy'
verbose_name_plural = 'Embassies'
【问题讨论】:
【参考方案1】:它不是那样工作的。 url 标签的参数——实际上就像任何模板标签一样——必须来自渲染时传递给模板的上下文。但是您正在尝试从表单本身动态使用值。
您应该从 URL 模式中完全删除参数。无论如何,您都没有在视图中使用它们,因为您从 request.POST 正确获取了值。
url(r'^search/$', views.search, name='search'),
...
<form action="% url 'search' %" ...
【讨论】:
现在我从views.py 中的selected_government = get_object_or_404(pk=request.POST['government'])
行得到get_object_or_404() missing 1 required positional argument: 'klass'
错误,但不确定它是什么意思。在我的代码中没有使用“klass”
你需要告诉那个函数使用什么模型:get_object_or_404(Government, pk=request.POST['government'])
.
我认为你的意思是Country
,但你没看错。【参考方案2】:
您需要使用ModelChoiceField
创建一个表单。
在 forms.py
中from django import forms
from models import Country
class SearchForm(forms.Form):
government = forms.ModelChoiceField(queryset=Country.objects.all(), to_field_name="code", label="Find Embassies sent by")
location = forms.ModelChoiceField(queryset=Country.objects.all(), to_field_name="code", label="that are located in")
在 views.py
中from forms import SearchForm
def index(request):
form = SearchForm()
context = 'form': form
return render(request, 'appname/index.html', context)
def search(request):
form = SearchForm(request.POST or None)
if request.POST and form.is_valid():
govt = form.cleaned_data.get('government')
loc = form.cleaned_data.get('location')
return HttpResponseRedirect(reverse('appname:results', kwargs="government": govt.code, "location": loc.code))
else:
context = 'form': form
return render(request, 'appname/index.html', context)
在 appname/urls.py 中 添加此网址
url(r'^search/$', views.search, name='search'),
在index.html
中<form method="post" action=% url 'appname:search' %>
% csrf_token %
form.as_p
<input type="submit" value="Search" />
</form>
【讨论】:
【参考方案3】:Django URL 解析器反向将关键字参数作为参数
reverse('search', kwargs='government':goverment.code, 'location':location.code)
希望对你有帮助
【讨论】:
谢谢,但它似乎不起作用,我仍然遇到同样的错误。 您没有在基本应用程序 url 中配置命名空间。所以你不应该需要 appname 作为前缀。更新了我的答案 你的意思是app_name = 'appname'
?
没有在你的基础应用 urls.py 中包含类似 include('appname.urls'), namespace='appname')
你是对的,但这似乎与我的问题无关。尤其是现在已经解决了。以上是关于Django HTML POST 参数导致 NoReverseMatch的主要内容,如果未能解决你的问题,请参考以下文章
django HttpResponseRedirect怎么传递参数