无法将 POST 参数传递给 Django 视图

Unable to pass POST parameter to Django view

我创建了一个 Django 视图和一个随附的 url。我试图让这个视图接受一个 POST 参数,但是这个东西不起作用。它是我正在设置的自定义应用程序的一部分,用于向移动设备发送推送通知。

我的views.py是:

class DeviceCreateView(FormView):
    model = DeviceObj
    form_class = DeviceForm
    template_name = "deviceobj_form.html"
    def form_valid(self, form): 
        if self.request.method == 'POST':
            reg_id = self.request.POST.get("registration_id")
            DeviceObj.objects.create(registration_id=reg_id)

我的urls.py是:

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^$', home, name='home'),
    url(r'^registration_id/$', DeviceCreateView.as_view(), name='registration_id'),
    url(r'^success/$', success, name='success'), 
]

我的模板是:

<form method="POST" action="{% url 'registration_id' %}">
{% csrf_token %}
<input type="hidden" name="registration_id" value="{{ registration_id }}">
</form>

我正在使用 POSTER add-on on Mozilla to try sending a POST parameter to the arrangement above. I POST to http://www.fakeurl.com/registration_id,将参数名称设置为 "registration_id",然后为其提供示例值(例如 "testing123")。作为回应,我得到一个 200 状态,带有以下转储:

<form method="POST" action="/registration_id/">
<input type='hidden' name='csrfmiddlewaretoken' value='PAPSwkpe1rU9c9ln4Jz0i6QKeyT57Cdf' />
<input type="hidden" name="registration_id" value="">
</form>  

如果我通过手动输入执行相同操作(即从输入标签中删除 type="hidden"),它会完美运行。但是使用 POSTER,我似乎无法获得 201(已创建)响应(即我的数据库中没有显示任何内容)。这件事已经困扰我好几天了!

两个问题

  1. form_valid() 在有效表单数据已发布时调用,因此您无需检查 GET/POST,您可以查看 django 文档中的示例 - https://docs.djangoproject.com/en/1.6/ref/class-based-views/generic-editing/#django.views.generic.edit.FormView

  2. redirect() 接受 model/view-name/url,而不仅仅是模板名称 https://docs.djangoproject.com/en/1.6/topics/http/shortcuts/

不清楚您要对这个隐藏字段做什么,但您应该通过模板中的 "form" 变量加载字段。

<form method="POST" action="{% url 'registration_id' %}">
{% csrf_token %}
{{ form }}
</form>

如果您需要隐藏一个字段,请尝试将其添加到您的表单中(我假设您使用的是 ModelForm,但您没有指定):

class DeviceForm(forms.ModelForm):
    class Meta:
        model = DeviceObj
        fields = ['registration_id']

    def __init__(self, *args, **kwargs):
        super(DeviceForm, self).__init__(*args, **kwargs)
        self.fields['registration_id'].widget = forms.HiddenInput()

更新

如以下评论所述,问题是通过 Mozilla POSTER 插件制作的 post 缺少 csrf_token。添加它允许 post 通过。