我正在尝试通过POST在我的网站上发送一个表单,但是,似乎POST URL的第一部分被切断,导致它无法匹配正确的URL。
我试图在模板中发送的表单:
<form action= "{% url 'change_portrait' %}" method="post">
{% csrf_token %}
<h5>Edit Portrait</h5>
<input type="hidden" name="portrait_id" value="{{image.pk}}">
<button type="submit" name="button" class="btn btn-primary">Submit Changes</button>
</form>
正确呈现为:
<form action= "/AdminDashboard/EditPortraits/ChangePortrait/" method="post">
<input type='hidden' name='csrfmiddlewaretoken' value='iCt1xvIc1KZXErhbcMNepk2daHXApGih' />
<h5>Edit Portrait</h5>
<input type="hidden" name="portrait_id" value="14">
<button type="submit" name="button" class="btn btn-primary">Submit Changes</button>
</form>
操作网址是正确的,也是我希望将表单提交到的位置。但是,当提交表单时,我会收到一条404,其中包含以下消息:
Using the URLconf defined in ZachWebsite.urls, Django tried these URL patterns, in this order:
^admin/
^AdminDashboard/
^ ^SundayPortraits/ [name='sunday_portraits']
^ ^Contact/ [name='contact_submission']
^ ^SubmitOrder/ [name='submit_buy_order']
^ ^BuyPrint/ [name='buy_print']
^ ^$ [name='index']
^ ^Login [name='login']
^ ^Logout [name='logout']
^ ^media\/(?P<path>.*)$
The current URL, EditPortraits/ChangePortrait/, didn't match any of these.
这是我的基础urls.py
urlpatterns = [
url(r'^AdminDashboard/', include('AdminDashboard.urls')),
url(r'^', include('mainApp.urls'))
]
和AdminDashboard.urls:
urlpatterns = [
url(r'^EditPortraits/ChangePortrait/', views.change_portrait, name='change_portrait'),
url(r'^EditPortraits/', views.edit_portraits, name='edit_portraits'),
url(r'^', views.dashboard, name='dashboard'),
]
由于某些原因,我不知道提交表单会切断最初的'/ AdminDashboard /',只针对剩余的网址'EditPortraits / ChangePortrait /'进行测试。这当然会导致它跳过基本urls.py中的第一个url模式(它应该去的地方),而是匹配catch所有第二个url,然后无法匹配mainApp.urls中的所有url。我不能为我的生活弄清楚为什么提交表单会切断行动URL的第一部分。它在内置的django开发服务器上按预期工作,但在部署到生产服务器时失败。
任何帮助都将非常感激。
修改
mainApp.urls(这些是跟踪中显示的内容,但绝不应该首先尝试):
urlpatterns = [
url(r'^SundayPortraits/', views.sunday_portraits, name='sunday_portraits'),
url(r'^Contact/', views.contact, name='contact_submission'),
url(r'^SubmitOrder/', views.submit_buy_order, name='submit_buy_order'),
url(r'^BuyPrint/', views.buy_print, name='buy_print'),
url(r'^$', views.index, name='index'),
url(r'^Login', views.login, name='login'),
url(r'^Logout', views.logout, name='logout')
]
views.change_portrait:
def change_portrait(request):
return HttpResponse('in')
这永远不会显示它永远不会进入视图。
编辑2:
还应注意,在表单提交时,浏览器中的URL是正确的:即显示“mysite.com/AdminDashboard/EditPortraits/ChangePortrait/”。 Django出于某种原因说当前的URL是'/ EditPortraits / ChangePortrait /'。如果我在浏览器中定期访问该URL('mysite.com/AdminDashboard/EditPortraits/ChangePortrait/'),它会正确加载页面。只有当我尝试POST到该页面时才会失败。
编辑3:
可以更新视图以正确接受POST变量,如下所示:
def change_portrait(request):
portrait_id = request.POST.get('portrait_id', None)
return HttpResponse('in')
然而,错误仍然存在。
编辑4:
查看呈现模板:
def edit_portraits(request):
if not request.session.get('logged_in', None):
return redirect('../')
portraits = Portrait.objects.filter(isSundayPortrait=True)
context = {'portraits': portraits,
'SundayPortraits': True}
return render(request, 'AdminDashboard/editportraits.html', context)
将url(r'^ EditPortraits / ChangePortrait /',views.change_portrait,name ='change_portrait')移动到mainApp.urls(尝试匹配)会导致更新的mainApp.urls:
urlpatterns = [
url(r'^SundayPortraits/', views.sunday_portraits, name='sunday_portraits'),
url(r'^Contact/', views.contact, name='contact_submission'),
url(r'^SubmitOrder/', views.submit_buy_order, name='submit_buy_order'),
url(r'^BuyPrint/', views.buy_print, name='buy_print'),
url(r'^$', views.index, name='index'),
url(r'^EditPortraits/ChangePortrait/$', views.change_portrait, name='change_portrait'),
url(r'^Login', views.login, name='login'),
url(r'^Logout', views.logout, name='logout')
]
mainApp.views.change_portrait:
def change_portrait(request):
if request.method == 'POST':
return HttpResponse('POST')
else:
return HttpResponse('GETTING')
使用与最初显示的相同的表单,执行get请求会导致HttpResponse'GETTING'按预期方式运行。将表单更改为POST请求会产生新的堆栈跟踪:
Request Method: POST
Request URL: http://www.example.com/EditPortraits/ChangePortrait/
Raised by: mainApp.views.change_portrait
Using the URLconf defined in ZachWebsite.urls, Django tried these URL patterns, in this order:
^admin/
^AdminDashboard/
^ ^SundayPortraits/ [name='sunday_portraits']
^ ^Contact/ [name='contact_submission']
^ ^SubmitOrder/ [name='submit_buy_order']
^ ^BuyPrint/ [name='buy_print']
^ ^$ [name='index']
^ ^EditPortraits/ChangePortrait/ [name='change_portrait']
^ ^Login [name='login']
^ ^Logout [name='logout']
^ ^media\/(?P<path>.*)$
The current URL, ChangePortrait/, didn't match any of these.
转移到mainApp.urls(它应该捕获它)现在切断该URL的第一部分'EditPortrait /',现在只测试'ChangePortrait /'
答案 0 :(得分:0)
在AdminDashboard.urls
中:
您的所有正则表达式都错过了$
注意:您的基础urls.py不需要在结尾处使用$
url(r'^EditPortraits/ChangePortrait/',
views.change_portrait, name='change_portrait')
好的是
url(r'^EditPortraits/ChangePortrait/$',
views.change_portrait, name='change_portrait')
答案 1 :(得分:0)
经过更多的调查和测试,我似乎已经找到了问题所在。结果是Django如何处理script_name和path_info的问题。由于表单是发布到子URL,因此URL'/ AdminDashboard /'的第一部分被截断并保存为script_name。 URL的其余部分“EditPortrait / ChangePortrait /”被保存为path_info。然后Django尝试将path_info与url匹配。显然它没有匹配任何东西,因为它缺少已保存在script_name中的url的第一部分。改变这一行:
self.path_info = path_info
在django.core.handlers.wsgi.py中:
self.path_info = script_name + path_info
修复了问题,现在正常运作。
答案 2 :(得分:0)
你说&#34;它在内置的Django开发服务器上按预期工作,但在部署到生产服务器时失败了。
对我而言,这表示在开发服务器上不存在的生产服务器上部署存在问题。例如,也许在生产服务器上,您使用的是Apache或NGINX等Web服务器,而您在开发时并未使用它。
我会检查并仔细检查任何基础设施,例如在Django之前获取请求的Web服务器,负载平衡器等,并确保它不会重写路径或以其他方式将错误的配置传递给Django。