自定义验证用户的电子邮件 Django ModelChoiceField



在我的模型中,我设置了一个自定义模型(CodeUser(,外键指向django.contrib.auth User模型。我实际上正在使用django-auth-ldap,但User模型是相同的。然后我有一个Code模型,它有一个custodian字段,它是特定CodeUser的外键。

class CodeUser(models.Model):
    user = models.ForeignKey('User')
    # Other fields...
class Code(models.Model):
    custodian = models.ForeignKey('CodeUser')
    # Other fields...

我正在使用Code模型的ModelForm,并希望表单接受custodian字段的CodeUser的电子邮件地址。我认为这可以通过简单地使用 ModelChoiceFieldto_field_name选项来完成。

但是,如果用户尚不存在,我希望能够创建用户。为此,我进行LDAP查询以确保电子邮件可以与用户关联,然后使用 populate django-auth-ldap 方法。

填充用户的过程工作正常,我只是无法弄清楚这段代码应该在我的 django 应用程序中的位置。我尝试创建一个自定义字段class,然后将其用于代码模型窗体中custodian字段的field_classes。我为我的字段实现了自定义validate方法,但在 Code ModelForm 验证期间从未调用此方法。似乎验证仅降级到模型窗体的模型中。

class UserByEmailField(forms.ModelChoiceField):
    def validate(self, value):
        # Check e-mail is valid
        # Check user already exists or populate from LDAP
    def to_python(self, value):
        # Return CodeUser instance
class CodeForm(forms.ModelForm):
    class Meta:
        fields = ['custodian']
        field_classes = {'custodian' : UserByEmailField}

最后,我的问题是,电子邮件地址的CodeUser验证/填充代码应该去哪里? 还有其他几种形式也需要此过程,因此我认为自定义字段类最有意义。

你可以在两个不同的地方做。 您可以覆盖代码表单的change_form.html并通过JavaScript执行此操作。

或者我过去所做的是在模型表单中执行此操作并覆盖"def clean"功能。 这是我在自定义更改密码表单中执行此操作的示例。

def clean(self):
    cleaned_data = super(ChangePasswordForm, self).clean()
    oldpass = cleaned_data.get('oldpassword')
    if not self.user.check_password(oldpass):
        raise forms.ValidationError("Invalid Password")
    pass1 = cleaned_data.get('password1')
    pass2 = cleaned_data.get('password2')
    if pass1 != pass2:
        raise forms.ValidationError("Passwords do not match")

也应该在模型表单中工作。

https://docs.djangoproject.com/en/1.9/ref/forms/validation/

最新更新