我有一个Django表单,它将向一个数据库添加一个条目,其中一个列具有唯一约束。如果提交尝试创建重复,我得到django.db.utls.IntegrityError
说明我违反了唯一约束(谢天谢地)。
处理Django表单时,有许多方法可以验证:
clean
方法clean_<field>
方法如果clear_<field>
方法引发django.forms.ValidationError
,则错误消息将附加到字段名称下_errors
字典中的列表中。使用clean
方法时,_errors
dict中的错误应为manually inserted。
现在,clean
和clean_<field>
方法听起来不是放置具有副作用的代码的好地方,我担心此时检查值是否唯一并不能保证我不会得到IntegrityError
。我宁愿尝试在数据库中创建行,并在违反约束时发出表单错误。
我的主要问题是表单会公开一个只读的公共属性errors
。因此,根据文档,我应该在我的表单中添加一个完成所有工作的方法,尝试在数据库中插入并在引发IntegrityError
时注册错误。因为验证后处理表单的操作需要大量其他数据,所以我不想将代码放在表单类本身中。
是否有任何其他(有记录的或未记录的)方法可以在课堂外的errors
词典中添加条目,或者我应该只是访问_errors
“私有”变量并且快乐接着就,随即?我知道这听起来像是一个OOP漏洞,但创建一个额外的方法只是为了访问这个“私有”变量在我看来似乎并不像任何人屏蔽任何东西。
修改
好像其他人已经提出a similar question,但似乎答案指向手动插入_errors
......
答案 0 :(得分:7)
目前,一个简单的解决方案如下:
try:
# Try to save model instance, which might throw `IntegrityError`.
# ...
except django.db.utils.IntegrityError:
# The form passed validation so it has no errors.
# Use the `setdefault` function just in case.
errors = django.forms.util.ErrorList()
errors = form._errors.setdefault(
django.forms.forms.NON_FIELD_ERRORS, errors)
errors.append('Sorry, this username is already in use.')
答案 1 :(得分:0)
我认为在表单中添加方法是非常合理的。 ModelForm类,它有一个save()方法,该方法执行将创建的实例保存到数据库的逻辑。如果您的表单可以从ModelForm继承(或者只是在表单中添加save()方法),那么您仍将处于“djangonian”标准之内。
http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#the-save-method