初始化并验证表单后更改BoundField值

时间:2019-01-24 09:21:29

标签: python django django-1.8

在CBV中初始化后,我试图手动更改表单字段的名称。您可以在初始化后执行以下操作:

form = self.get_form()  # it is initialized here
form.cleaned_data['name'] = form.instance.name + ' (new)'

但是我需要在验证后更改值,因此form.cleaned_data不再涉及。我需要直接更改BoundField的值。我怎样才能做到这一点?或者我该如何以其他方式来做我想做的事情?

以下是我的观点和形式课:

class MyView(CBV):
    def form_valid(self, form):
        if copy:
            form.instance.pk = None
            name = form.instance.name + ' (new)'
            form.instance.name = name
            # it does work this way
            data = form.data.copy()
            data['name'] = name
            form.data = data
            self.object = form.save()
        else:
            pass
        return self.render_to_response(self.get_context_data(form=form))

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

    def __init__(self, *args, **kwargs):
        self.copy = kwargs.get('copy', False)
        super(MyForm, self).__init__(*args, **kwargs)

    def clean_name(self):
        # (1) doing this has no effect in the displayed form included in the response of a POST request
        # (2) I don't always want to do this, only when a form is valid
        cleaned_data = self.cleaned_data['name']
        if self.copy:
            cleaned_data['name'] += ' (new)'
        return cleaned_data

2 个答案:

答案 0 :(得分:1)

您可以覆盖清除方法。继承表单后,您可以在验证后修改您的cleaned_data。

def clean(self)
    # It will validate data
    self.cleaned_data = super().clean()
    # do what you want
    self.cleaned_data['name'] = 'blah...'
    return self.cleaned_data

或者您可以在此情况下使用特定字段的名称。

def clean_name(self):
    data = self.cleaned_data.get('name', '')
    if not data:
        raise forms.ValidationError("You must enter a name")

    if not data.endswith('( new)'):
        return data += '( new)'
    return data

ADD

您可以在super().clean()之后看到实际上已经<完成>完成的验证。 您可以检查打印self.is_valid(),然后可以看到它是True。或者只是在该行中添加调试器以检查验证是否已完成

def clean(self):
    # It will validate data
    self.cleaned_data = super().clean()
    # Check validation is already done here
    # Or debugging it
    # from IPython import embed; embed() 
    print(self.is_valid())
    # do what you want
    return self.cleaned_data

答案 1 :(得分:0)

您应该先使用commit=False保存表单,然后在实例中进行更改。

def form_valid(self, form):
    if copy:
        instance = form.save(commit=False)
        instance.pk = None
        name = instance.name + ' (new)'
        instance.save()
        return...

(此外,发布成功后,您应该始终重定向,而不是渲染模板。)