【问题标题】:How can I change a Django form field value before saving?如何在保存之前更改 Django 表单字段值?
【发布时间】:2012-02-14 01:11:12
【问题描述】:
if request.method == 'POST':
    userf = UsersModelForm(request.POST)
    username = userf.data['username']
    password = userf.data['password']
    passwordrepeat = userf.data['passwordrepeat']
    email = userf.data['email']

我试过了:

    tempSalt = bcrypt.gensalt()
    password = bcrypt.hashpw(password,tempSalt)
    passwordrepeat = bcrypt.hashpw(passwordrepeat,tempSalt)

    userf.data['password'] = password
    userf.data['passwordrepeat'] = passwordrepeat

但我得到了错误。如何在保存之前更改userf.data['password']userf.data['passwordrepeat'] 的值?

错误:

AttributeError at /register

This QueryDict instance is immutable

Request Method:     POST
Request URL:    http://127.0.0.1:8000/register
Django Version:     1.3.1
Exception Type:     AttributeError
Exception Value:    

This QueryDict instance is immutable

Exception Location:     /usr/local/lib/python2.6/dist-packages/django/http/__init__.py in _assert_mutable, line 359
Python Executable:  /usr/bin/python
Python Version:     2.6.6
Python Path:    

['/home/user1/djangoblog',
 '/usr/lib/python2.6',
 '/usr/lib/python2.6/plat-linux2',
 '/usr/lib/python2.6/lib-tk',
 '/usr/lib/python2.6/lib-old',
 '/usr/lib/python2.6/lib-dynload',
 '/usr/local/lib/python2.6/dist-packages',
 '/usr/lib/python2.6/dist-packages',
 '/usr/lib/python2.6/dist-packages/gst-0.10',
 '/usr/lib/pymodules/python2.6',
 '/usr/lib/pymodules/python2.6/gtk-2.0']

【问题讨论】:

  • 你有什么样的错误?验证错误,完整性错误?您必须始终发布错误消息。总是。
  • 我已经更新了错误,再看一遍就明白了。
  • 我们也需要你想做的事情:设置一个默认值,如果值不存在就设置一个值,如果它不好就更正一个值,等等。django 表单上有几个钩子。
  • 我已经更新了原始帖子/问题。再看一遍就明白了。
  • 它没有告诉我们你想做什么,它告诉我们使用你在做什么。你想要什么结果?不是在编程级别,而是在功能级别。

标签: python django forms model save


【解决方案1】:

如果您需要在保存之前对数据做一些事情,只需创建如下函数:

def clean_nameofdata(self):
    data = self.cleaned_data['nameofdata']
    # do some stuff
    return data

您只需要创建一个名称为 **clean_***nameofdata* 的函数,其中 nameofdata 是该字段的名称,因此如果要修改密码字段,您需要:

def clean_password(self):

如果需要修改密码重复

def clean_passwordrepeat(self):

所以在里面,只需加密您的密码并返回加密的密码。

我的意思是:

def clean_password(self):
    data = self.cleaned_data['password']
    # encrypt stuff
    return data

因此,当您验证表单时,密码将被加密。

【讨论】:

  • 我不明白你的问题。在哪里?在 clean_foo 中,您会得到纯密码并对其进行转换。
  • 我的意思是我会在哪里创建这些 def clean_password(self): 函数?
  • 哦,没错,在您创建的表单类中。
  • 应该是'self.cleaned_data['password']'(你忘记了最后一个代码块中的'ed')
【解决方案2】:

请参阅save() 方法的文档

if request.method == 'POST':
    userf = UsersModelForm(request.POST)
    new_user = userf.save(commit=False)

    username = userf.cleaned_data['username']
    password = userf.cleaned_data['password']
    passwordrepeat = userf.cleaned_data['passwordrepeat']
    email = userf.cleaned_data['email']

    new_user.password = new1
    new_user.passwordrepeat = new2

    new_user.save()

【讨论】:

  • 这是一种更新。是否可以在保存前更改/修改值?
【解决方案3】:

如果您需要从 POST 填写表单、更改任何表单字段值并再次呈现表单,您将遇到问题。 这是它的解决方案:

class StudentSignUpForm(forms.Form):
  step = forms.IntegerField()

  def set_step(self, step):
    data = self.data.copy()
    data['step'] = step
    self.data = data

然后:

form = StudentSignUpForm(request.POST)
if form.is_valid() and something():
  form.set_step(2)
  return  render_to_string('form.html', {'form': form})

【讨论】:

  • 我有一个类似的问题,我有两个提交按钮。第一个创建预览,第二个是实际提交。通过使用 POST 数据创建表单(自然),未提交按钮的值将被清除。此方法非常适合恢复未单击按钮的值。
  • 这很好,很灵活
【解决方案4】:

覆盖_clean 方法并放置your checks in them。你可以从那里修改cleaned_data

例如:

def clean_password(self):
    new1 = self.cleaned_data['password']
    return new1

表单中的每个字段都会有一个由 Django 自动创建的 field_name_clean() 方法。执行form.is_valid()时会调用此方法。

【讨论】:

  • 我无法理解。你能发布完整的代码和解释吗?那会很有帮助。
  • ModelForm 不是 Form,clean_data 是否可用于 ModelForm?
  • clean_passwor(self):函数什么时候调用?
  • 这是完整的代码。我添加了文档的链接。它适用于任何形式,包括模型形式。该功能在模型保存前自动触发。
【解决方案5】:

观看次数:

def post(self, request, *args, **kwargs):
    form = self.form_class(request.POST)
    if form.is_valid():
        obj = form.save(commit=False)
        obj.my_field = 'value'
        obj.save()

在表单中:

instance = form.instance
instance.user = request.user
instance.save()

但要小心,这不会检查is_valid()。如果您想这样做,您可以使用新值实例化表单:

# NOT TESTED, NOT SURE IF THIS WORKS...
form = MyForm(instance=instance)
if form.is_valid():
    form.save()

【讨论】:

    猜你喜欢
    • 2015-06-07
    • 1970-01-01
    • 2016-06-29
    • 1970-01-01
    • 2021-01-12
    • 1970-01-01
    • 2022-01-23
    • 2014-06-15
    • 2022-01-01
    相关资源
    最近更新 更多