Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 初始化和验证表单后更改BoundField值_Python_Django_Django 1.8 - Fatal编程技术网

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

Python 初始化和验证表单后更改BoundField值,python,django,django-1.8,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的值。我该怎么做?或者,我怎样才能以任何其他方式做我正试图做的事情 以下是我的一些观点和形式: cl

我试图在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

您可以重写clean方法。在继承表单之后,您可以在验证之后修改您的数据

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
添加 您可以看到在
super().clean()之后实际上已经完成了验证。
您可以检查print
self.is\u valid()
,然后您可以看到它是真的。或者在该行中添加调试器以检查验证是否已完成

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

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

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

(另外,在成功发布后,您应该始终重定向,而不是呈现模板。)

使用form.validated_data如何?@seuling该属性似乎不存在于表单实例中,我将其与drf混淆。请尝试清除数据或仅使用form.data-之后可以使用它validation@seuling正如我在我的问题
表单中所说的那样,清理的\u数据
不起作用。而且
form.data
是不可变的。然后您可以自定义clean方法。或者,最好使用
clean_field
方法自定义特定字段,因为我说过我不想将值设置为验证级别。验证表单时使用clean方法。我需要在验证后更改字段值(并且仅当表单有效时)。在任何情况下,即使在验证过程中,它也不起作用。好的。。。您必须先查看django表单代码。()在超级清理()方法之后,表单已验证。也不好。似乎
form.data
将覆盖任何数据,甚至是已清理的数据。我尝试的唯一方法是创建不可变的
form.data
的副本,并直接修改
'name'
键。但这似乎不是正确的方法。@dabadaba我不确定你到底想要什么。在clean()中创建form.data或clean_数据的副本有什么区别?这就是“clean()”方法存在的原因。如果表单无效,如何防止更改?(对,我只是模拟了代码,我实际返回的响应是json)当表单无效时,
form\u valid
不会被调用。这解决了你的问题吗?如果是的话,请接受答案,作为对未来搜索者的一个标志。我还没有机会尝试。别担心,如果它解决了问题,我会接受的。这也不行。确保它正在使用已更改的名称保存实例(无论如何,它已经正确地执行了此操作),但它没有使用名称字段中的正确名称在成功响应中加载表单。