警告:
下面的代码是为老版本的django编写的(之前
Custom
User Models
介绍)。它包含一个竞赛条件,并且
只应与事务隔离级别一起使用
SERIALIZABLE
并请求范围内的事务。
因为字段实例的属性是只读的,所以代码无法工作。恐怕比你想象的要复杂一点。
如果只使用表单创建用户实例,则可以定义强制执行此行为的自定义模型表单:
from django import forms
from django.contrib.auth.models import User
class UserForm(forms.ModelForm):
class Meta:
model = User
def clean_email(self):
email = self.cleaned_data.get('email')
username = self.cleaned_data.get('username')
if email and User.objects.filter(email=email).exclude(username=username).exists():
raise forms.ValidationError(u'Email addresses must be unique.')
return email
然后只要在需要创建新用户的任何地方使用此表单。
顺便说一句,你可以用
Model._meta.get_field('field_name')
按名称而不是按位置获取字段。例如:
# The following lines are equivalent
User._meta.fields[4]
User._meta.get_field('email')
更新
Django文档建议您使用
clean
用于跨多个窗体字段的所有验证的方法,因为在
<FIELD>.clean
和
<FIELD>_clean
方法。这意味着您可以(主要)依赖字段的值
cleaned_data
从内
清洁的
.
因为表单域是按照声明的顺序进行验证的,所以我认为偶尔可以将多字段验证放在
<现场清洁
方法,只要相关字段出现在它所依赖的所有其他字段之后。我这样做是为了使任何验证错误都与字段本身相关,而不是与表单相关。