【问题标题】:Django: how to cleanup form fields and avoid code duplicationDjango:如何清理表单字段并避免代码重复
【发布时间】:2011-02-26 23:54:22
【问题描述】:

我经常需要在使用某些表单数据之前对其进行过滤(保存到数据库等)。假设我想在大多数文本字段中,以多种形式去除空格并用一个空格替换重复的空格。使用clean_<fieldname> 方法做到这一点并不难:

# Simplified model with two text fields
class MyModel(models.Model):
    title = models.CharField()
    description = models.CharField()

# Model-based form
class MyForm(forms.ModelForm):
    class Meta:
        model = MyModel

    def clean_title(self):
        title = self.cleaned_data['title']
        return re.sub(r'\s{2,}', ' ', title.strip())

    def clean_description(self):
        description = self.cleaned_data['description']
        return re.sub(r'\s{2,}', ' ', description.strip())

它完全符合我的需要,并且有一个我喜欢的很好的副作用:如果用户只输入空格,该字段将被视为空,因此无效(如果需要),我什至不必抛出ValidationError

这里明显的问题是代码重复。即使我为此创建一些函数,比如my_text_filter,我也必须为我所有表单中的每个文本字段调用它:

from myproject.filters import my_text_filter

class MyForm(forms.ModelForm):
    class Meta:
        model = MyModel

    def clean_title(self):
        return my_text_filter(self.cleaned_data['title'])

    def clean_description(self):
        return my_text_filter(self.cleaned_data['description'])

问题:在 Django 中是否有任何标准和简单的方法(如果重要,我使用 1.2 版)来做到这一点(例如,通过将属性 validators = {'title': my_text_filter, 'description': my_text_filter} 添加到 MyModel),或者至少更多还是不太标准的解决方法?我在文档中阅读了有关表单验证和验证器的信息,但在那里找不到我需要的内容。

【问题讨论】:

  • 如果您想同时为多个字段做某事,您可以使用表单的clean 方法,而不是为每个字段编写一个!

标签: django django-forms filtering


【解决方案1】:

据我所知,Django 没有任何本地解决方案来解决您的问题。 我只能展示我如何为自己解决这个问题。 我建议你为你的 ModelForm 使用decorator。 这里的工作代码(我也使用日志记录模块):

#DECORATOR
def applyValidators(model_form):
    def apply(*args,**kwargs):
        try:
            if hasattr(model_form.Meta.model,"validators"):
                for field_name,fnc in model_form.Meta.model.validators.items():
                    setattr(model_form,"clean_%s" % field_name,fnc)
        except Exception,err:
            logging.error(str(err))
        return model_form(*args,**kwargs)
    return apply

#VALIDATORS
def validator(*args,**kwargs):
    return "SOMEVALUE"

#MODEL
class MyModel(models.Model):
    #Your fields
    .......
    .......
    .......

    #VALIDATE DICT
    validators = {"username":validator,"email":validator}    

#MODEL FORM
@applyValidators
class MyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel
    .......
    .......
    .......

【讨论】:

  • 装饰器的使用非常好。会记住这一点的。
猜你喜欢
  • 2021-06-20
  • 2011-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-16
  • 2014-03-07
相关资源
最近更新 更多