码迷,mamicode.com
首页 > 其他好文 > 详细

form组件, ModelForm组件

时间:2018-11-11 15:01:36      阅读:233      评论:0      收藏:0      [点我收藏+]

标签:aries   import   组件   auth   sage   html   ova   长度   错误信息   

一:form组件功能
  form 组件:
1.效验
2.页面显示错误信息
3.渲染页面
4.只要错误信息重置

 

二: form组件的语法:

技术分享图片

fm=BookForm({"title":"yuan","price":123,"email":"123"})
fm.is_valid()
# 如果效验失败就返回False
# 如果效验成功就返回True
fm.cleaned_data  返回校成功的数据
{对的数据的键值:对的数据的值}
fm.errors    返回效验错误的数据,后面是列表
{错的键值:[错误信息,]}
必须先is_valid 才能取出对的和错的数据

 

注意:

技术分享图片

 

  form表单里的所有字段必须给值,如果不给值就会报错,但是如果给的多就不会报错,

  clean-data里只有效验成功的字段

 

三.form 组件应用

实例:注册用户

 模型:model.py

class UserInfo(models.Model):
    user=models.CharField(max_length=32)
    pwd=models.CharField(max_length=32)
    email=models.CharField(max_length=32)

 

 form组件: (写在哪个里都可以)

from django.forms import widgets(需要导入)
class UserForm(forms.Form):
    msg = {"required": 该字段不能为空, "invalid": "格式错误", "min_length": "长度不可以小于五"}  # invalid只适用于邮箱
    # error_messages  自定义错误信息,label  自定义lable显示文字
    user = forms.CharField(min_length=5,
                           error_messages=msg,
                           label=用户名,
                           widget=widgets.TextInput(attrs={"class": "form-control"}))
    pwd = forms.CharField(min_length=5, error_messages=msg, label=密码,
                          widget=widgets.PasswordInput(attrs={"class": "form-control"}))
    r_pwd=forms.CharField(error_messages=msg, label=确认密码,
                          widget=widgets.PasswordInput(attrs={"class": "form-control"}))
    email = forms.EmailField(error_messages=msg, label=邮箱, widget=widgets.EmailInput(attrs={"class": "form-control"}))

 视图函数:

 

方式一:

 views,py里 

def reg(request):
    if request.method=="GET":
        return render(request,reg.html)
    if request.method=="POST":
        # 数据校验
        # 直接把它放进来做校验就可以request里多一个crsf-token也没事多余一个也不会报错
        form=UserFrom(request.POST)
        if form.is_valid():
            print(form.cleaned_data)
        else:
            print("来自errorcleaned",form.cleaned_data)
            print("哈哈",form.errors)
            # 因为后面是列表所以需要
            # print(‘哈哈1‘,form.errors.get(‘user‘)[0])
            error=form.errors
            return render(request,"reg.html",{error:error})

 

对应的模板里HTML

 # novalidate   让浏览器对你放行不进行拦截
    <form action="" method="post" novalidate>
        {% csrf_token %}
        <p>用户名<input type="text" name="user"></p><span class="error">{{ error.user.0 }}</span>
        <p>密码<input type="password" name="‘pwd"></p><span class="error">{{ error.pwd.0 }}</span>
        <p>邮箱<input type="text" name="email"></p><span class="error">{{ error.email.0 }}</span>
        <p><input type="submit"></p>
    </form>

 

 

 方式二:

views.py  

def reg(request):

    if request.method=="POST":
        form = UserFrom(request.POST)
        if form.is_valid():
            print(form.cleaned_data)
        else:
            error = form.errors
            return  render(request,reg.html,locals())

    form=UserFrom()
    return render(request, "reg.html", locals())

 

 模板:

# 不能对应加错误
<form action="" method="post">
    {% csrf_token %}
    {{ form.as_p }}

    <p><input type="submit"></p>
</form>

 

方式三:

模板:

方式三直接传过来,对的不会重置
<form action="" method="post" novalidate>
    {% csrf_token %}
    <p>用户名{{ form.user }}</p><span class="error">{{ error.user.0 }}</span>
    <p>密码{{ form.pwd }}</p><span class="error">{{ error.pwd.0 }}</span>
    <p>邮箱{{ form.email }}</p><span class="error">{{ error.email.0 }}</span>
    <p><input type="submit"></p>
</form>

 

 方式四:

模板:

{#方式四#}
{#用最后这个就行#}
<form action="" method="post" novalidate>
    {% csrf_token %}

    {% for field in form %}
        <div>
        <lable for=‘‘>{{ field.label }}</lable>
        {{ field }}<span class="error">{{ field.errors.0 }}</span>
        </div>
    {% endfor %}
    <div><input type="submit">提交</div>
</form>

 field就是:{{form.user}}

 技术分享图片

 

 

form 组件的使用流程:

源码解析is_valid(self)#self是自定义组件对象

技术分享图片

 self._errors = ErrorDict()

技术分享图片

如果不加钩子就结束了,如果加钩子继续:

代码:
        form=UserForm(request.POST)
        
        类的实例化:实际上是完成一次赋值,  
            self.field={"user":user,pwd:pwd,"email":email}
                    后面的值都是类实例化出来的对象,是各自的规则
                     user=forms.CharField(min_length=5,
                         label="用户名",
                         error_messages=msg,
                         widget=widgets.TextInput(attrs={"class":"form-control"})
                         )
                        pwd=forms.CharField(error_messages=msg,
                                               label="密码",
                                              widget=widgets.PasswordInput(attrs={"class":"form-control"})
                                               )
                        email=forms.EmailField(error_messages={"invalid":"邮箱格式错误"},
                                               label="邮箱",
                                               widget=widgets.EmailInput(attrs={"class":"form-control"})
                                               )
                            form.is_valid()
                           
    self._clean_fields() #效验字段                       
    #效验数据
        
        
        def _clean_fields(self):
        
        #field是各自的规则,name是字段字符串
        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.
            # UserForm({"user":"yuan",‘pwd‘:123,‘email‘:"123"})
            if field.disabled:
                value = self.get_initial_for_field(field, name)
            else:
                # value就是 yuan 等
                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:
                
                    #field是校验规则,value是  yuan 如果校验不成功直接跳到except里
                    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_user(self):
        val = self.cleaned_data.get(user)
        print(val)
        # user_obj = auth.authenticate(username=val)
        from django.contrib.auth.models import User
        user_obj=User.objects.filter(username=val).first()

        print("haha",user_obj)
        if user_obj:
            raise ValidationError(用户名已存在)

        else:
            return val

    def clean_pwd(self):
        pwd = self.cleaned_data.get(pwd)
        if pwd.isdigit():
            raise ValidationError(密码是纯数字)

        else:
            return pwd

    def clean_email(self):
        import re
        email = self.cleaned_data.get(email)
        if re.search([0-9a-zA-Z]+@163\.com, email):
            return email
        else:
            raise ValidationError(请输入格式化为@163.com邮箱)
   # 全局勾的错误的键为"__all___"
    def clean(self):
        pwd = self.cleaned_data.get("pwd")
        r_pwd = self.cleaned_data.get("r_pwd")
        print(r_pwd)
        if pwd and r_pwd:
            if pwd == r_pwd:
                return self.cleaned_data
            else:
                raise ValidationError(两次密码不一致!)
        else:
            return self.cleaned_data

 可以给他起个别名,省着显示错误信息得时候还得判断:

def clean(self):
        password =  self.cleaned_data.get(password)
        r_pwd= self.cleaned_data.get(r_pwd)
        print(password,r_pwd)

        if password==r_pwd:
            print(haha)
            return self.cleaned_data
        else:
            self.add_error(r_pwd,ValidationError(密码不一致))

 

 

 

 

 

 

 

 

 

 

 

 

 

  

form组件, ModelForm组件

标签:aries   import   组件   auth   sage   html   ova   长度   错误信息   

原文地址:https://www.cnblogs.com/2275114213com/p/9942029.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!