诚意
诚意如你,当一诚的态度对待

导航

 

一:自定义匹配规则案例-注册-局部钩子

实现目标:用户名不能重复、密码不能是纯数字

数据库表结构

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

后端代码

1:匹配规则

from django import forms
from app01.models import UserInfo
from django.core.exceptions import NON_FIELD_ERRORS, ValidationError  #错误管理
from django.forms import widgets   #widgets魔法工具包

class UserForm(forms.Form):  #创建校验规则类。,必须继承forms组件类
    name=forms.CharField(min_length=5,label="用户名")
    pwd=forms.CharField(label="密码")
    email=forms.EmailField(label="邮箱")

    # 自定义钩子(匹配规则)
    # 用户名不能重复
    def clean_name(self):
        val=self.cleaned_data.get('name')  #先取值
        ret=UserInfo.objects.filter(name=val)  #查看数据库中是否有这个值
        if not ret: #如果在数据库中没有,就通过匹配
            return val
        else:#否则,说明在数据库中有该用户名
            raise ValidationError("用户名已存在")
    # 密码不能是纯数字
    def clean_pwd(self):
        val = self.cleaned_data.get('pwd')  # 先取值
        print(type(val))
        if val.isdigit():  #判断是否是数字
            raise ValidationError("密码不能是纯数字")
        else:
            return val

 

2:视图函数

def reg(request):
    if request.method=='POST':
        form=UserForm(request.POST)    #把数据放在规则类里校验
        if form.is_valid():#校验数据
            UserInfo.objects.create(**form.cleaned_data) #符合规则后我们把数据插入到数据库中,因为数据是字典,所以需要打散
        else:
            error=form.errors
            return render(request,'reg.html',locals())  #把错误数据渲染到模板
    else:
        form=UserForm()  #没有把我们输入的数据放进去查看是否匹配规则。我们的目的是把UserForm规则类的字段渲染到页面
        return render(request,'reg.html',locals()) 

前端代码

    <form action="" method="post" novalidate>
        {% csrf_token %}
        {% for field in form %}
            <div>
            <label for="">{{ field.label }}</label>   {#  显示字段名:#}
            {{ field }}{#  显示input框:#}
            <span class="error">{{ field.errors }}</span>  {#  显示错误信息:#}
            </div>
        {% endfor %}
        
        <input type="submit">
    </form>

 

效果:

二:自定义匹配规则案例-注册-全局钩子

1:实现目标:

需要 确认密码 和 密码 进行比对。

2:数据库表结构

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

 

3:后端代码

from django import forms
from app01.models import UserInfo
from django.core.exceptions import NON_FIELD_ERRORS, ValidationError  #错误管理
from django.forms import widgets   #widgets魔法工具包

class UserForm(forms.Form):
    name=forms.CharField(min_length=5,label="用户名")  
    pwd=forms.CharField(label="密码")
    r_pwd=forms.CharField(label="确认密码")
    email=forms.EmailField(label="邮箱")

    # 自定义局部钩子
    # 用户名不能重复
    def clean_name(self):
        val=self.cleaned_data.get('name')
        ret=UserInfo.objects.filter(name=val)
        if not ret:
            return val
        else:
            raise ValidationError("用户名已存在")
    # 密码不能是纯数字
    def clean_pwd(self):
        val = self.cleaned_data.get('pwd')
        print(type(val))
        if val.isdigit():
            raise ValidationError("密码不能是纯数字")
        else:
            return val

    def clean(self):#全局钩子
        pwd=self.cleaned_data.get("pwd")  #有可能第一层校验未通过取值是空
        r_pwd=self.cleaned_data.get("r_pwd")
        print("=======>")
        if pwd and r_pwd: #如果两个都通过了第一层说明clean_data中有值就是true
            if pwd==r_pwd:
                print(1111)
                return self.cleaned_data
            else:
                print(222222)
                raise ValidationError("两次密码不一致")
        else:  #如果两个不在clean_data里,那就没必要在比较了,因为本身就已经在errors里了
            return self.cleaned_data

 

视图函数

def reg(request):
    if request.method=='POST':
        form=UserForm(request.POST)   
        if form.is_valid():#校验数据
            UserInfo.objects.create(**form.cleaned_data) 
        else:
            error=form.errors
            if form.errors.get("__all__"):#第二层全局错误,__all__:全局错误信息
                g_error=form.errors.get("__all__")[0]
            return render(request,'reg.html',locals())  #把错误数据渲染到模板
    else:
        form=UserForm()  
        return render(request,'reg.html',locals())

 

4:前端代码

    <form action="" method="post" novalidate>
        {% csrf_token %}
        {% for field in form %}
            <div>
            <label for="">{{ field.label }}</label>   {#  显示字段名:#}
            {{ field }}{#  显示input框:#}
            <span class="error">{{ field.errors }}</span>  {#  显示错误信息:#}
            {% if field.label == "确认密码" %}
                <span>{{ g_error|default:"" }}</span>
            {% endif %}
            </div>
        {% endfor %}
        
        <input type="submit">
    </form>

5:效果

 

 三:Forms组件自定义规则函数(钩子)----源码分析

从上面的案例中我们知道了如何自定义一个钩子函数,那么为什么是那样写的呢?

这一切都在源码中有定义------>参看源码分析:博文   Django-源码-Forms组件--自定义规则(钩子)

 

posted on 2018-11-03 15:53  诚意  阅读(234)  评论(0编辑  收藏  举报