Python 在清理之前修改进入django表单的数据

Python 在清理之前修改进入django表单的数据,python,django,Python,Django,在清理之前,我需要修改进入表单的数据。我成功了,但看起来很糟糕: def __init__(self, *args, **kwargs): if len(args) > 0: data = args[0] elif 'data' in kwargs: data = kwargs['data'] else: data = None if data i

在清理之前,我需要修改进入
表单的数据。我成功了,但看起来很糟糕:

    def __init__(self, *args, **kwargs):
        if len(args) > 0:
            data = args[0]
        elif 'data' in kwargs:
            data = kwargs['data']
        else:
            data = None
        if data is not None:
            data['content'] = ' '.join(data['content'].strip().split())
        super(TagForm, self).__init__(*args, **kwargs)

有一些简洁的解决方案吗?

您可以将
if
/
elif
/
else
压缩到一行,非常简单:

def __init__(self, *args, **kwargs):
    data = args[0] if args else kwargs.get('data', None)
    if data:
        data['content'] = ' '.join(data['content'].strip().split())
    super(TagForm, self).__init__(*args, **kwargs)
if args
if len(args)>0
一样有效,因为
length==0
项为
False
length>0
项为
True


if data
if data not None
一样有效,因为您假设
data
至少有一个键,如果它
not None
,并且如果它有一个键,则它是
True

,如中所述,您无法在表单级别执行此操作,因此
\u init\u
方法似乎是最合法的方法。当然,您也可以在将数据传递到表单之前修改数据(例如在视图中或处理表单的任何位置)

我找到了另一个解决方案:

def clean(self, *args, **kwargs):
    data = dict(self.data)
    if 'content' in data:
        content = data['content']
        if isinstance(content, list):
            content = content[0] # QueryDict wraps even single values to list
        data['content'] = ' '.join(content.strip().split())
    self.data = data # I do this trick becouse request.POST is immutable
    return super(MyForm, self).clean(*args, **kwargs)
UPD:错误修复:
super(self.\uuuuu class\uuuuuu,self)
如果使用表单继承,可能会导致无限递归:)


UPD:似乎仍有问题,无法正常工作。

数据
作为
\uuuu init\uuuu
方法的第一个参数,与超级类
表单
相同。这样,您就不必在
args
kwargs
中挖掘

def __init__(self, data=None, *args, **kwargs):
    if data is not None:
        data = data.copy() # make it mutable
        data['content'] = ' '.join(data['content'].strip().split())
    super(TagForm, self).__init__(data, *args, **kwargs)

很好用,谢谢。但是我在PEP 8中读到,将
is
is not
None
一起使用更适合于代码样式。您要求使用
简洁的
解决方案,因此我尽可能缩短了它。在这种情况下,
False
is-None
具有相同的效果,在许多情况下,您只想将
None
视为
None
,因此您应该使用
is
来避免意外地认为
False
is
None
的数据需要在if语句中用引号括起来。为了使它更简短,您可以使用data=args和args[0]或kwargs.get('data',None)。@raratiru这是不等价的。你只是在操纵名称,而不是真正地改变任何对象。下面是实际发生的情况:
>>args=[{“content”:“foo”}]>>data=args[0]>>data[“content”]=“bar”>>args[{'content':'bar'}]
对于典型的用例,
form=MyForm(request.POST)
,querydict
request.POST
是不可变的,因此您不能就地修改。在我的回答中,我确实使用了
data=data.copy()
来获取可变的查询信息。在Django 1.11中,我收到了以下错误:
super()。\uuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,请问一个新问题。事实上,这是一个非常古老的帖子,谢谢你的回复。我找到了!
super()
行的
data=data
部分导致错误。以下内容非常有用:
super(TagForm,self)。\uuuu init\uuuu(data,*args,**kwargs)
@raratiru你说得对。Django管理员将
request.FILES
作为参数传递,因此我们需要将
数据
更改为位置参数,以避免
类型错误
。我已经按照你的建议更新了答案。