我可以将 Django 表单转换为 GET 请求字符串吗?

Joe*_*Joe 4 django django-forms

我想采用现成的形式(即从经过django.Forms.form验证的绑定数据派生的类的对象)并对它进行 urlencode,就好像它是通过 GET 提交的一样。有内置的方法吗?

为了说明为什么我要问这个问题,以及为什么我不能只调用urlencode,其输出应该是“ box=on”。

from django import forms
from urllib import urlencode


class DemoForm(forms.Form):
    box = forms.BooleanField(required=False)

instance = DemoForm({"box": True})  # it's irrelevant how this data is supplied
instance.is_valid()
print "encoded:", urlencode(instance.cleaned_data)
Run Code Online (Sandbox Code Playgroud)

事实上它是“ box=True”,因为urlencode它不是对形式进行编码,而是对清理后的值进行编码(相信我,BooleanField这是最简单的情况)。

所以我要求一种对表单进行编码的方法,就好像它是一个 GET 字符串一样。正确的 GET 字符串。

GDo*_*orn 5

在表单的 clean_data 上调用 urllib 的 urlencode 在两种情况下不会很好地工作:

  • 如果您使用的是 ModelChoiceField,cleaned_data 将包含实际对象,而不是 ID。这些将 urlencode() 到它们的字符串表示形式而不是它们的主键。
  • 如果您使用的字段可以保存多个值(例如 MultiValueField、MultipleChoiceField 或其他),urlencode() 将丢失该字段中除一个值之外的所有值。所以 {'mykey':[1,2,3]} 变成 ?mykey=3 而不是 ?mykey=1&mykey=2&mykey=3 django 的方式。

要解决这两个问题,请使用表单的内置 urlencode 函数:

form = MyForm(request.POST) #or a dict or whatever
form.is_valid()
querystring = form.data.urlencode() 
Run Code Online (Sandbox Code Playgroud)

请注意,这是对数据调用的,而不是对 clean_data 调用的。如果您的表单在验证过程中更改了值,这些更改将不会反映在此处。

  • 如果现在有人偶然发现这一点,那么 Django 1.10 及更高版本显然不再支持这一点。`从 django.utils.http 导入 urlencode; querystring = urlencode(form.data,doseq=True)` 会为你做的。 (3认同)