Django

一、校验字段功能

1、reg页面准备

models

from django.db import models

class UserInfo(models.Model):
    useranme = models.CharField(max_length=32)
    password = models.CharField(max_length=32)
    email = models.EmailField()
    telephone = models.CharField(max_length=32)

生成数据表

python manage.py makemigrations
python manage.py migrate

常规的form

路由层urls

from app01 import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('reg/', views.reg),
]

视图层views:

def reg(request):
    if request.method=='POST':
        print(request)
        pwd=request.POST.get('pwd')
        re_pwd=request.POST.get('re_pwd')
        if pwd==re_pwd:
            print(request.POST)
            return HttpResponse('注册成功')
        else:
            return HttpResponse('密码错误')

    return render(request,'reg.html')

模板层.html

<body>
    <form action="" method="post">
        {% csrf_token %}
        <p>用户名<input type="text" name="user"></p>
        <p>密码<input type="password" name="pwd"></p>
        <p>确认密码<input type="password" name="re_pwd"></p>
        <p>电话<input type="number" name="tel"></p>
        <p>邮箱<input type="email" name="email"></p>
        <input type="submit">
    </form>
</body>

2、(form组件)定义规则

-----------------------------------------------------

print(request.POST):
{'user': 'yuan', 'pwd': '1234', 're_pwd': '1235', 'email': '123@qq.com', 'tel': '123'}

注意

 

 总结校验字段功能

1、模板层form表单的name=‘属性值’必须与 form组件字段名称一致

2、定义class UserForm(forms.Form)

3、对前段传来的数据进行验证:form=UserForm(request.POST)

4、判断验证是否成功,布尔值form.is_valid()

5、print(form.cleaned_data)# 存放匹配成功的键值对  print(form.errors) # 存放 键:失败的信息

 

二、forms组件的渲染标签功能

方式一

views

from django.shortcuts import render, HttpResponse
from django import forms   # 导入forms组件
# 定义校验规则
class UserForm(forms.Form):
    name = forms.CharField(min_length=4, max_length=10)
    pwd = forms.CharField(min_length=4)
    re_pwd = forms.CharField(min_length=4)
    email = forms.EmailField()
    tel = forms.CharField()
def reg_html(request):
    form = UserForm()
    return render(request, 'reg_html.html', locals())

reg.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h3>渲染标签功能1</h3>
<form action="" method="post">
{% csrf_token %}
<p>用户名
{{ form.user }}
</p>
<p>密码{{ form.pwd }}</p>
<p>确认密码{{ form.re_pwd}}</p>
<p>电话{{ form.tel }}</p>
<p>邮箱{{ form.email }}</p>
<input type="submit">
</form>
</body> </html>
可实现相同的功能

 

方式二

 reg.html

<h3>渲染方式2</h3>
   <form action="" method="post">
        {% csrf_token %}
        {% for field in form %}
        <div>
            {{ field.label }}
            {{ field }}
        </div>
        {% endfor %}
    </form>

可以自己设置label属性

方式3

<h3>渲染方式3</h3>
<form action="" method="post">
    {% csrf_token %}
    {{ form.as_p }}
     <input type="submit">
</form>

三、显示error与重置输入信息功能

 reg.html

<h3>渲染标签方式1</h3>
    <form action="" method="post" novalidate>
        {% csrf_token %}
        <p> {{ form.user.label }}
            {{ form.user }}<span>{{ form.user.errors.0 }}</span>
        </p>
        <p>{{ form.pwd.label }}{{ form.pwd }} <span>{{ form.pwd.errors.0 }}</span></p>
        <p>{{ form.re_pwd.label }}{{ form.re_pwd}}<span>{{ form.re_pwd.errors.0 }}</span></p>
        <p>{{ form.tel.label }}{{ form.tel }}<span>{{ form.tel.errors.0 }}</span></p>
        <p>{{ form.email.label }}{{ form.email }}<span>{{ form.email.errors.0 }}</span></p>
        <input type="submit">
    </form>

views.py

def reg(request):
    if request.method=='POST':
        print(request)
        print(request.POST)
        form=UserForm(request.POST)
        print(form.is_valid()) # 返回布尔值
        if form.is_valid():
            print(form.cleaned_data)
            return HttpResponse('ok')
        else:
            print(form.cleaned_data)# 存放匹配成功的键值对
            print(form.errors)      # 存放 键:失败的信息
            return render(request, 'reg.html', locals())
        
    form=UserForm()
    return render(request, 'reg.html', locals())

说明:

四、forms组件的参数配置

1、参数提示参数设置

views.py

from django.forms import widgets
## 定义校验规则
class UserForm(forms.Form):
    # min_length最低为4位
    user=forms.CharField(min_length=4,label='用户名'
                         ,error_messages={'required':'该字段不为空', 'min_length': '不能少于4个字符'},

                         widget=widgets.TextInput(attrs={'class':'form-control'}))# 默认lable=User
    pwd=forms.CharField(min_length=4,label='密码',widget=widgets.PasswordInput(attrs={'class': 'form-control'})
                        )
    re_pwd=forms.CharField(min_length=4,label='确认密码',widget=widgets.PasswordInput(attrs={'class': 'form-control'}))
    email=forms.EmailField(label='邮箱',widget=widgets.EmailInput(attrs={'class': 'form-control'})
                           , error_messages={'invalid': '格式错误'})
    tel=forms.CharField(label='电话',widget=widgets.NumberInput(attrs={'class': 'form-control'}))

2、引入bootstrap模块优化界面

reg.html引入

<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

reg.html

novalidate
<div class="container"> <div class="row"> <div class="col-md-6 col-lg-offset-3"> <h3>渲染标签方式1</h3> <form action="" method="post" novalidate> {% csrf_token %} <p> {{ form.user.label }} {{ form.user }}<span>{{ form.user.errors.0 }}</span> </p> <p>{{ form.pwd.label }}{{ form.pwd }} <span>{{ form.pwd.errors.0 }}</span></p> <p>{{ form.re_pwd.label }}{{ form.re_pwd}}<span>{{ form.re_pwd.errors.0 }}</span></p> <p>{{ form.tel.label }}{{ form.tel }}<span>{{ form.tel.errors.0 }}</span></p> <p>{{ form.email.label }}{{ form.email }}<span>{{ form.email.errors.0 }}</span></p> <input type="submit"> </form> </div> </div> </div>

 五、forms组件的局部钩子

1、ValidationError:验证错误

models

from django.db import models

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

froms组件,如何进行验证错误?

from django import forms

from django.forms import widgets
from app01.models import UserInfo
from django.core.exceptions import ValidationError  # 导入验证错误
## 定义校验规则
class UserForm(forms.Form):
    # min_length最低为4位
    user=forms.CharField(min_length=4,label='用户名'
                         ,error_messages={'required':'该字段不为空', 'min_length': '不能少于4个字符'},

                         widget=widgets.TextInput(attrs={'class':'form-control'}))# 默认lable=User
    pwd=forms.CharField(min_length=4,label='密码',widget=widgets.PasswordInput(attrs={'class': 'form-control'})
                        )
    re_pwd=forms.CharField(min_length=4,label='确认密码',widget=widgets.PasswordInput(attrs={'class': 'form-control'}))
    email=forms.EmailField(label='邮箱',widget=widgets.EmailInput(attrs={'class': 'form-control'})
                           , error_messages={'invalid': '格式错误'})
    tel=forms.CharField(label='电话',widget=widgets.NumberInput(attrs={'class': 'form-control'}))

    # 局部钩子
    def clean_user(self):
        val=self.cleaned_data.get('user')

        ret=UserInfo.objects.filter(useranme=val)# 数据库中的user
        if not ret:
            return ret
        else:
            raise ValidationError('该用户已经注册')  # 验证错误
def reg(request):
if request.method=='POST':
print(request)
print(request.POST)
form=UserForm(request.POST)
print(form.is_valid()) # 返回布尔值
if form.is_valid():
print(form.cleaned_data)
return HttpResponse('ok')
else:
print(form.cleaned_data)# 存放匹配成功的键值对
print(form.errors) # 存放 键:失败的信息
return render(request, 'reg.html', locals())

form=UserForm()
return render(request, 'reg.html', locals())
 

forms组件源

模板层不变

提交与数据库姓名重名的结果

2、校验方法:clean_name 源码

在模板层加样式属性,让错误信息显示颜色

<span style="color: red">{{ form.pwd.errors.0 }}</span>

4、全局钩子校验

 <form action="" method="post" novalidate>

 {# novalidate 当提交表单时不对表单数据(输入)进行验证#}

 模板

# forms组件
from django.forms import widgets

wid_01=widgets.TextInput(attrs={"class":"form-control"})
wid_02=widgets.PasswordInput(attrs={"class":"form-control"})

from django.core.exceptions import ValidationError
class UserForm(forms.Form):
    name=forms.CharField(max_length=32,
                         widget=wid_01
                         )
    pwd=forms.CharField(max_length=32,widget=wid_02)
    r_pwd=forms.CharField(max_length=32,widget=wid_02)
    email=forms.EmailField(widget=wid_01)
    tel=forms.CharField(max_length=32,widget=wid_01)

    # 局部钩子
    def clean_name(self):
        val=self.cleaned_data.get("name")
        if not val.isdigit():
            return val
        else:
            raise ValidationError("用户名不能是纯数字!")

    # 全局钩子

    def clean(self):
        pwd=self.cleaned_data.get("pwd")
        r_pwd=self.cleaned_data.get("r_pwd")

        if pwd==r_pwd:
            return self.cleaned_data
        else:
            raise ValidationError('两次密码不一致!')

def register(request):

    if request.method=="POST":
        form=UserForm(request.POST)
        if form.is_valid():
            print(form.cleaned_data)       # 所有干净的字段以及对应的值
        else:
            clean_error=form.errors.get("__all__")

        return render(request,"register.html",locals())
    form=UserForm()
    return render(request,"register.html",locals())

视图

<form action="" method="post" novalidate>
            {% csrf_token %}

            {% for field in form %}
                <div>
                    <label for="">{{ field.label }}</label>
                    {{ field }}
                    <span class="pull-right" style="color: red">
                          {% if field.label == 'R pwd' %}
                          <span>{{ clean_error.0 }}</span>
                          {% endif %}
                          {{ field.errors.0 }}
                    </span>
                </div>
            {% endfor %}
            <input type="submit" class="btn btn-default">
</form>

--------------------------------

   # 直接覆盖父类的clean方法, 全局钩子
    def clean(self):
        pwd = self.cleaned_data.get("pwd")
        r_pwd = self.cleaned_data.get("r_pwd")

        # 先判断是否接受到pwd,r_pwd的值
        if pwd and r_pwd:
            if pwd == r_pwd:
                return self.cleaned_data
            else:
                raise ValidationError("两次密码不一致")
        else:
            return self.cleaned_data

 总结:forms组件解耦,调用冲突

把form组件内容单独放一个模块中,不要放在views.py中

原文地址:https://www.cnblogs.com/foremostxl/p/9976012.html