from django import forms from django.core.exceptions import ValidationError from jax import models class RegForm(forms.Form): username = forms.CharField( max_length=16, label="用户名", error_messages={ "max_length": "用户名最长16位", "required": "用户名不能为空!", }, widget=forms.TextInput( attrs={"class":"form-control", "placeholder": "用户名"}, ) ) password = forms.CharField( min_length=6, label="密码", error_messages={ "required": "密码不能为空", "min_length": "密码不能少于6位", }, widget = forms.PasswordInput( attrs={"class": "form-control", "placeholder": "密码"}, ) ) re_password = forms.CharField( min_length=6, label="确认密码", error_messages={ "required": "密码不能为空", "min_length": "密码不能少于6位", }, widget=forms.PasswordInput( attrs={"class": "form-control", "placeholder": "密码"}, ) ) email = forms.EmailField( label="邮箱", error_messages={ "invalid": "请输入正确的邮箱格式", "required": "邮箱不能为空", }, widget=forms.EmailInput( attrs={"class": "form-control", "placeholder": "邮箱"}, ) ) # 重写全局的钩子函数,对确认密码做校验 def clean(self): password = self.cleaned_data.get("password") re_password = self.cleaned_data.get("re_password") if re_password and re_password != password: self.add_error("re_password", ValidationError("两次密码不一致")) else: return self.cleaned_data # 重写username局部钩子 def clean_username(self): username = self.cleaned_data.get("username") is_exist = models.UserInfo.objects.filter(username=username) if is_exist: self.add_error("username", ValidationError("该用户已经存在!")) else: return username # 重写email局部钩子 def clean_email(self): email = self.cleaned_data.get("email") is_exist = models.UserInfo.objects.filter(email=email) if is_exist: self.add_error("email", ValidationError("该邮箱已经注册!")) else: return email
django的form表单中定义的字段,都有对应的id以及方法,例如id_username、clean_username,这里的方法均为django中forms.Form源码类BaseForm定义
例:
def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=ErrorList, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None): self.is_bound = data is not None or files is not None self.data = {} if data is None else data self.files = {} if files is None else files self.auto_id = auto_id if prefix is not None: self.prefix = prefix self.initial = initial or {} self.error_class = error_class # Translators: This is the default suffix added to form field labels self.label_suffix = label_suffix if label_suffix is not None else _(':') self.empty_permitted = empty_permitted self._errors = None # Stores the errors after clean() has been called. # The base_fields class attribute is the *class-wide* definition of # fields. Because a particular *instance* of the class might want to # alter self.fields, we create self.fields here by copying base_fields. # Instances should always modify self.fields; they should not modify # self.base_fields. self.fields = copy.deepcopy(self.base_fields) self._bound_fields_cache = {} self.order_fields(self.field_order if field_order is None else field_order)
def _clean_fields(self): for name, field in self.fields.items(): # value_from_datadict() gets the data from the data dictionaries. # Each widget type knows how to retrieve its own data, because some # widgets split data over several HTML fields. if field.disabled: value = self.get_initial_for_field(field, name) else: value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name)) try: if isinstance(field, FileField): initial = self.get_initial_for_field(field, name) value = field.clean(value, initial) else: value = field.clean(value) self.cleaned_data[name] = value if hasattr(self, 'clean_%s' % name): value = getattr(self, 'clean_%s' % name)() self.cleaned_data[name] = value except ValidationError as e: self.add_error(name, e)
def clean(self): """ Hook for doing any extra form-wide cleaning after Field.clean() has been called on every field. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field named '__all__'. """ return self.cleaned_data def has_changed(self): """Return True if data differs from initial.""" return bool(self.changed_data)