我正試圖通過電子郵件和電話在網站上實施註冊。用戶可以通過電話或電子郵件或兩者都註冊。如果用戶同時保留電話和電子郵件字段爲空,則會提出ValidationError
,「您不能將電話和電子郵件字段留空,必須填寫至少一個字段。」在Django ModelForm中可以同時使用`clean`和`clean_fieldname`方法嗎?
我們有單獨的clean
方法username, email, phone, password
。我不想在save()
上實施上述驗證。我不想在用戶模型中定義clean
方法。 我已經爲這個表單寫了測試,並且他們通過了。但如果我同時使用clean
和clean_fieldname
,可能會出現什麼錯誤?在處理視圖時會不會成爲問題?
我有3個問題:
- 我可以使用在 形式既
clean_fieldname
和clean
方法呢? - 以什麼其他方式我可以確保用戶至少註冊 電話或電子郵件?
clean()
和validate()
如何工作?我已閱讀django文檔,但我完全不理解它。
這是我實施的代碼。
class RegisterForm(SanitizeFieldsForm, forms.ModelForm):
email = forms.EmailField(required=False)
message = _("Phone must have format: +9999999999. Upto 15 digits allowed."
" Do not include hyphen or blank spaces in between, at the"
" beginning or at the end.")
phone = forms.RegexField(regex=r'^\+(?:[0-9]?){6,14}[0-9]$',
error_messages={'invalid': message},
required=False)
password = forms.CharField(widget=forms.PasswordInput())
MIN_LENGTH = 10
class Meta:
model = User
fields = ['username', 'email', 'phone', 'password',
'full_name']
class Media:
js = ('js/sanitize.js',)
def clean(self):
super(RegisterForm, self).clean()
email = self.data.get('email')
phone = self.data.get('phone')
if (not phone) and (not email):
raise forms.ValidationError(
_("You cannot leave both phone and email empty."
" Signup with either phone or email or both."))
def clean_username(self):
username = self.data.get('username')
check_username_case_insensitive(username)
if username.lower() in settings.CADASTA_INVALID_ENTITY_NAMES:
raise forms.ValidationError(
_("Username cannot be 「add」 or 「new」."))
return username
def clean_password(self):
password = self.data.get('password')
validate_password(password)
errors = []
email = self.data.get('email')
if email:
email = email.split('@')
if email[0].casefold() in password.casefold():
errors.append(_("Passwords cannot contain your email."))
username = self.data.get('username')
if len(username) and username.casefold() in password.casefold():
errors.append(
_("The password is too similar to the username."))
phone = self.data.get('phone')
if phone:
if phone_validator(phone):
phone = str(parse_phone(phone).national_number)
if phone in password:
errors.append(_("Passwords cannot contain your phone."))
if errors:
raise forms.ValidationError(errors)
return password
def clean_email(self):
email = self.data.get('email')
if email:
if User.objects.filter(email=email).exists():
raise forms.ValidationError(
_("Another user with this email already exists"))
return email
def clean_phone(self):
phone = self.data.get('phone')
if phone:
if User.objects.filter(phone=phone).exists():
raise forms.ValidationError(
_("Another user with this phone already exists"))
return phone
def save(self, *args, **kwargs):
user = super().save(*args, **kwargs)
user.set_password(self.cleaned_data['password'])
user.save()
return user
實際上,[驗證者文檔](https://docs.djangoproject.com/en/1.11/ref/forms/validation/)也明確地解釋了這個順序。 –