Django 中的“您通过 POST 调用了此 URL,但该 URL 未以斜杠结尾”错误

问题描述 投票:0回答:10

我正在尝试通过输出 Json 在 Django 中创建一个 REST API。如果我在终端中使用 curl 发出 POST 请求,我会遇到问题。我得到的错误是:

您通过 POST 调用了此 URL,但该 URL 未以斜杠结尾且 你有 APPEND_SLASH 集。 Django 无法重定向到斜杠 URL 同时维护 POST 数据。更改您的表单以指向 127.0.0.1:8000/add/(注意尾部斜杠),或在 Django 设置中设置 APPEND_SLASH=False。

我的url.py是:

from django.conf.urls.defaults import patterns, include, url
import search

# Uncomment the next two lines to enable the admin:
# from django.contrib import admin
# admin.autodiscover()

urlpatterns = patterns('',
    
    url(r'^query/$', 'search.views.query'),
    url(r'^add/$','search.views.add'),
)

我的观点是:

# Create your views here.
from django.http import HttpResponse
from django.template import Context,loader
import memcache
import json

def query(request):
    data=['a','b']
    
    mc=memcache.Client(['127.0.0.1:11221'],debug=0)
    mc.set("d",data);

    val=mc.get("d")
    
    return HttpResponse("MEMCACHE: %s<br/>ORIGINAL: %s" % (json.dumps(val),json.dumps(data)) )

def add(request):
    #s=""
    #for data in request.POST:
    #   s="%s,%s" % (s,data)
    s=request.POST['b']
    return HttpResponse("%s" % s)

我知道它没有提供 Json 但我在终端中发出 POST 请求时遇到了上述问题

curl http://127.0.0.1:8000/add/ -d b=2 >> output.html

虽然我是 django 的新手。

python django rest post django-urls
10个回答
56
投票

首先,请确保您将请求发送至

http://127.0.0.1/add/
而不是
http://127.0.0.1/add
.

其次,您可能还想通过添加

@csrf_exempt
装饰器来免除 csrf 处理的视图 - 因为您没有从 cURL 发送适当的令牌。


43
投票

为了 URL 的一致性,Django 有一个名为

APPEND_SLASH
的设置,如果它不是以这种方式发送的,它总是在 URL 的末尾附加一个斜杠。这确保
/my/awesome/url/
始终从该 URL 提供服务,而不是同时提供
/my/awesome/url
and
/my/awesome/url/
.

然而,Django 通过自动将末尾没有斜杠的版本重定向到末尾有斜杠的版本来实现这一点。重定向不携带请求的状态,因此当发生这种情况时,您的 POST 数据将被丢弃。

你需要做的就是确保当你发送你的POST时,你将它发送到最后带有斜杠的版本。


4
投票

只需从您的 URL 中删除尾部斜杠

urlpatterns = [
    path('', views.home, name= 'home'),
    path('contact/', views.contact, name= 'contact'),
    path('about/', views.about, name= 'about')
]

改为

urlpatterns = [
    path('', views.home, name= 'home'),
    path('contact', views.contact, name= 'contact'),
    path('about', views.about, name= 'about')
]

在 HTML 表单中添加尾部斜线

 <form method="POST" action="/contact/">
    {% csrf_token %}

对我有用


2
投票

获取==>http://127.0.0.1:8000/create?name=wpwqekhqw/

对于 POST ==> http://127.0.0.1:8000/create/?name=wpwqekhqw/

你应该在 POST ... request 中创建之后添加'/'


1
投票

在 Html 中更改操作。 它在我的案例中有效。

<form action="{% url 'add' %}" method="post">
    {% csrf_token %}
    ...
</form>

0
投票

Another scenario can raise the exact error, not related to either csrf or APPEND_SLASH solution, 下面是一个例子。

 def post(self, request, *args, **kwargs):
        data= request.data
        print(data['x'])

如果有效载荷主体中不存在“x”,数据['x']将引发错误,在我的例子中,这个错误给出了一个像上面那样的错误消息。 希望这会帮助其他开发人员。


0
投票

删除 url.py 上的斜线

例如: 来自:

url(r'^customer/json/set_person/$', views.json_set_person, name='fog.apps.views.json.set_person'),

致:

url(r'^customer/json/set_person$', views.json_set_person, name='fog.apps.views.json.set_person'),

0
投票

可以通过“/?”提供带有和不带尾部斜线的网址:

在 django 3.X 中:

from django.urls import re_path
re_path(r'^query/?$', 'search.views.query'),
re_path(r'^add/?$','search.views.add'),

0
投票

就我而言,我在使用

AjaxAdmin
时忘记添加
simple-ui

来自:

@admin.register(xxx)
class xxxAdmin(ExportActionMixin, GAdmin):

致:

@admin.register(xxx)
class xxxAdmin(ExportActionMixin, GAdmin, AjaxAdmin):

0
投票

我在 Django 上使用 Stripe Webhook 时遇到了同样的错误:

RuntimeError:您通过 POST 调用了此 URL,但该 URL 未以 一个斜杠,你已经设置了 APPEND_SLASH。 Django 无法重定向到 在维护 POST 数据的同时斜线 URL。更改您的表单以指向 localhost:8000/stripe_webhooks/(注意尾部斜杠),或设置 APPEND_SLASH=False 在你的 Django 设置中。

因为即使我在主文件夹

/
中用
urls.py
定义了url
core
,其中
settings.py
如下所示:

# "core/urls.py"

from my_app.views import stripe_webhooks

urlpatterns = [
                  # Here ↓
    path("stripe_webhooks/", stripe_webhooks, name="stripe_webhooks")
]

然后,我在下面没有

/
的情况下运行命令:

                                             # Without "/" ↓
./stripe listen --forward-to localhost:8000/stripe_webhooks

所以为了解决错误,我把

/
如下图所示:

                                                    # Here ↓
./stripe listen --forward-to localhost:8000/stripe_webhooks/

或者,我从 url 中删除了

/
,如下所示:

# "core/urls.py"

from my_app.views import stripe_webhooks

urlpatterns = [
                      # ↓ "/" is removed
    path("stripe_webhooks", stripe_webhooks, name="stripe_webhooks")
]

然后,我在下面没有

/
的情况下运行命令:

                                             # Without "/" ↓
./stripe listen --forward-to localhost:8000/stripe_webhooks
© www.soinside.com 2019 - 2024. All rights reserved.