【问题标题】:Change Django Form Data before it's processed在处理之前更改 Django 表单数据
【发布时间】:2010-09-29 02:37:27
【问题描述】:

我有一个模型的表单,它有两个字段:field_A 和 field_B。我想:

  • 呈现表单时:仅显示 field_A
  • 当我调用 form.save() 时,field_B 会使用 field_A 中的值保存在模型中

我尝试过的:

field_A = forms.CharField(required=True)
field_B = forms.CharField(required=False)

def save(self, *args, **kwargs):
     """
     Overriding save, so call the parent form save and return the new_user
     object.
     """
     self.data["field_B"] = self.data["field_A"]
     self.cleaned_data["username"] = self.cleaned_data["email"]
     super(MyParentClass*, self).save(*args, **kwargs) 

*这两个字段都继承自 ParentClass,它们是必需的

【问题讨论】:

    标签: django django-forms


    【解决方案1】:

    这是一个对我有用的解决方案。

    # models.py
    class MyModel(models.Model):
        field_A = models.CharField(max_length = 255)
        field_B = models.CharField(max_length = 255)
    
        def __unicode__(self):
            return "%s: %s, %s" % (self.pk, self.field_A, self.field_B)
    
    # forms.py
    class MyModelForm(ModelForm):
        class Meta:
            model = MyModel
            exclude = ('field_B',)
    
        def save(self, *args, **kwargs):
            commit = kwargs.pop('commit', True)
            instance = super(MyModelForm, self).save(*args, commit = False, **kwargs)
            instance.field_B = self.cleaned_data['field_A']
            if commit:
                instance.save()
            return instance
    

    表格Meta的解释

    exclude = ('field_B',)
    

    确保满足您的第一个条件。当表单显示给用户时,只显示field_A。第二个条件在重写的save() 方法中得到解决。

    save()的解释

    commit = kwargs.pop('commit', True)
    

    提取 commit 关键字参数(如果提供)。

    instance = super(MyModelForm, self).save(*args, commit = False, **kwargs)
    

    创建底层模型的实例。显式传递commit=False 以确保此实例尚未保存到数据库中。

    instance.field_B = self.cleaned_data['field_A']
    

    field_A 的值从cleaned_data 分配给实例的field_B。请记住,您应该在此之前致电form.is_valid()。否则将没有cleaned_data

            if commit:
                instance.save()
    

    如果用户希望将实例保存到数据库中,请执行此操作。

    return instance
    

    最后,返回实例。

    示例用法

    In [1]: from app.forms import MyModelForm
    
    In [2]: f = MyModelForm(data = {'field_A': 'Value A'})
    
    In [3]: f.is_valid()
    Out[3]: True
    
    In [4]: f.save()
    Out[4]: <MyModel: 3: Value A, Value A>
    
    In [5]: f = MyModelForm(data = {'field_A': 'VA'})
    
    In [6]: f.is_valid()
    Out[6]: True
    
    In [7]: f.save(commit = False)
    Out[7]: <MyModel: None: VA, VA>
    
    In [8]: 
    

    【讨论】:

    • 这是一个大规模的黑客攻击......输入来自用户名等模型表单的非用户可编辑模型数据的正确方法应该是什么?
    • @Xster:您的答案是我为usermodified_by 等字段所做的方式。我的回答迎合了一个非常具体的要求。我在生产中从来没有遇到过这样的情况。
    猜你喜欢
    • 2011-10-30
    • 1970-01-01
    • 2013-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-10
    • 1970-01-01
    • 2012-03-14
    相关资源
    最近更新 更多