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
isNone
的数据需要在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)
,querydictrequest.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
作为参数传递,因此我们需要将数据
更改为位置参数,以避免类型错误
。我已经按照你的建议更新了答案。