【问题标题】:How to dump request.POST to dict, maintaining multiple value fields?如何将 request.POST 转储到 dict,维护多个值字段?
【发布时间】:2016-06-16 10:53:30
【问题描述】:

我想将ModelForm 数据存储在数据库中,在JSONField 中,以便以后能够从该数据创建对象,只需调用:

form = ModelForm(data_from_jsonfield_as_querydict)
if form.is_valid():
    object = form.save()

问题 1:

我在 POST 中有数据:

>>> print request.POST
{u'field-1': u'value1', u'field-2': [u'value-2a', u'value-2b']}

我必须将这个QueryDict 转换为dict。但是,如果我打电话给request.POST.dict(),我会丢失字段 2 的列表值:

>>> print request.POST.dict()
{'field-1': 'value1', 'field-2': 'value-2b'}

我尝试使用request.POST.getlist,但随后我将所有值作为列表获取:

>>> for k in request.POST.keys():
...     print request.POST.getlist(k)
[u'value1']
[u'value-2a', u'value-2b']

我什至无法检查上面循环中的给定值是否是列表实例,因为如果值是列表,request.POST.get(k) 不会返回错误,另一方面,request.POST[k] 会为每个字段返回 MultiValueDictKeyError

我想到的唯一解决方案是循环遍历getlist() 获得的所有字段并将单值列表转换为字符串,但在我看来这有点矫枉过正。

问题 2:

假设问题 1 已解决并且我有 dict 并将表单数据存储在数据库中,如下所示:

# object.data
{u'field-1': u'value1', u'field-2': [u'value-2a', u'value-2b']}

当我想使用上面的dict作为表单数据创建对象时,我必须将它转换为QueryDict,这可以通过以下方式完成:

querydict = QueryDict('', mutable=True)
querydict.update(object.data)

然后:

form = ModelForm(querydict)

问题是,当从dict 使用一些列表实例值创建querydict 时,所有querydict 值都包含在列表中:

print querydict
{u'field-1': [u'value1'], u'field-2': [[u'value-2a', u'value-2b']]}

因此,field-2 的表单验证失败,因为该字段的 getlist 返回列表列表(带有一个值)而不是值列表。

【问题讨论】:

  • 这似乎只有在您动态构建表单并且无法知道表单生成时的内容时才有必要......在这种情况下,您可能应该是以包含您的类型的方式定义您的字段。如果这不是您正在做的事情,您可能想退后一步,重新考虑这是否是解决您试图解决的任何问题的好方法(实际上,将其放在您的问题中会得到更有用的答案)。
  • 您能否描述预期的dict 您想将此示例POST 转换为?
  • @kungphu 我不认为在不丢失list 数据的情况下将QueryDict 转换为dict 是不寻常的。无论如何,我重新编辑了我的问题。
  • 这不是我的意思。这只是使用 Django 的一部分,具有多个值的输入需要使用 getList;坦率地说,我不太喜欢它,但这就是框架处理该用例的方式;实际上,您的选择是使用框架提供的内容(通常是一个好主意)或子类化/覆盖它提供的类/函数(这有时也是一个很好的解决方案)。哪种适合您完全取决于您的具体情况。

标签: python django dictionary


【解决方案1】:

您必须将 MultiValueDict 与 QueryDict 一起添加,

from django.http.request import QueryDict, MultiValueDict

dictionary = {'key_1': ['1'], 'key_2': ['1', '2'], }
query_dict = QueryDict('', mutable=True)
query_dict.update(MultiValueDict(dictionary))

【讨论】:

    【解决方案2】:

    您可以使用lists()。该格式与dict 构造函数兼容。

    post_data = dict(request.POST.lists())
    

    【讨论】:

    • 是的,但是所有dict 值都将是列表。当然,我可以使用{k: v[0] if len(v) == 1 else v for k, v in request.POST.lists()},它可以回答我的问题,但我认为它会更简单。
    • 这个功能的实际实现是MultiValueDict
    【解决方案3】:

    我相信

    json.dumps(query_dict)

    可能是您正在寻找的。 来自JSON encoder and decoder

    【讨论】:

    • 不幸的是,json.dumps(request.POST) 充当request.POST.dict() 并丢失了列表值。
    猜你喜欢
    • 2016-02-05
    • 2017-07-01
    • 2014-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-27
    • 2020-01-13
    • 2017-03-09
    相关资源
    最近更新 更多