Django form组件

form组件介绍

form组件的主要功能如下:

  • 生成页面可用的HTML标签
  • 对用户提交的数据进行校验
  • 保留上次输入内容

form组件的数据校验功能

views.py 文件

from django.shortcuts import render, HttpResponse
from django import forms

# 定义一个类,继承 forms.Form
class MyForm(forms.Form):
    name = forms.CharField(max_length=16, min_length=6, required=True)
    pwd = forms.CharField(max_length=16, min_length=6, required=True)
    email = forms.EmailField()
    '''
    注:
    required = True 必填字段
    max_length = 16 最大长度
    min_length = 16 最小长度
    '''
    
def index(request):
    dic = {'name': 'qwrasds', 'pwd': 1234567, 'email': '33@qq.com'}

    # 实例化时需传入字典类型的参数
    my = MyForm(dic)

    # is_valid 为true时,表示校验成功,反之为校验失败
    if my.is_valid():
        # 校验通过的数据 cleaned_data
        print(my.cleaned_data)
        return HttpResponse('ok')
    else:
        print(my.cleaned_data)
        # 校验失败的信息
        print(my.errors)
    return HttpResponse('wrong')

用form组件实现注册功能

准备工作

  • 不使用form组件渲染的模板
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户注册</title>
</head>
<body>
<form action="" method="post">
    <p>用户名:<input type="text" name="name"></p>
    <p>密码:<input type="text" name="pwd"></p>
    <p>邮箱:<input type="text" name="email"></p>
    <input type="submit" value="注册">
</form>
</body>
</html>
  • 使用form组件渲染模板页面
<!DOCTYPE html>
<html lang="en">
<head>
    {% load static %}
    <meta charset="UTF-8">
    <link rel="stylesheet" href="{% get_static_prefix %}bootstrap-3.3.7/css/bootstrap.min.css">
    <title>用户注册</title>
</head>
<body>
<!-- 方法一 -->
<form action="" method="post">
    <p>用户名:{{ my_from.name }}</p>
    <p>密码:{{ my_from.pwd }}</p>
    <p>邮箱:{{ my_from.email }}</p>
    <input type="submit" value="注册">
</form>

<!-- 方法二 (推荐使用)-->
<!-- 使用时可在字段的参数中设置 label='中文' -->
<form action="" method="post">
    {% for foo in my_from %}
        <p>{{ foo.label }}:{{ foo }}</p>
    {% endfor %}
    <input type="submit" value="注册">
</form>

<!-- 方法三 -->
<!-- 使用 as_p/as_table/as_ul -->
<form action="" method="post">
    {{ my_from.as_p }}
    <input type="submit" value="注册">
</form>
</body>
</html>
index.html
  • 使用form组件渲染错误信息
from django.shortcuts import render, HttpResponse
from django import forms
from django.forms import widgets


# forms 组件数据校验的功能

# 定义一个类,继承 forms.Form
class MyForm(forms.Form):
    name = forms.CharField(max_length=8, min_length=4, required=True, label='用户名',
                           error_messages={'max_length': '用户名不能多于8位字符或数字',
                                           'min_length': '用户名不能少于4位字符或数字',
                                           'required': '必填字段'},
                           widget=widgets.TextInput(attrs={'class': 'form-control'}))
    pwd = forms.CharField(max_length=11, min_length=6, required=True, label='密码',
                          error_messages={'max_length': '密码不能多于11位字符或数字',
                                          'min_length': '密码不能少于6位字符或数字',
                                          'required': '必填字段'},
                          widget=widgets.PasswordInput(attrs={'class': 'form-control'}))
    email = forms.EmailField(label='邮箱', error_messages={'required': '必填字段',
                                                         'invalid': '不符合邮箱格式'},
                             widget=widgets.EmailInput(attrs={'class': 'form-control'}))


     '''
     注:
     required = True 必填字段
     max_length = 16 最大长度
     min_length = 16 最小长度
     label='用户名' 设置中文显示
     error_messages={'required': '必填字段'} 错误信息渲染
     widget = widgets.TextInput(attrs={'class': 'form-control'}) 输入框的类型及样式
     '''


def index(request):
    if request.method == 'GET':
        my_from = MyForm()
    elif request.method == 'POST':
        my_from = MyForm(request.POST)
    return render(request, 'index.html', locals())
views.py
<!DOCTYPE html>
<html lang="en">
<head>
    {% load static %}
    <meta charset="UTF-8">
    <link rel="stylesheet" href="{% get_static_prefix %}bootstrap-3.3.7/css/bootstrap.min.css">
    <title>用户注册</title>
</head>
<body>
<form action="" method="post">
    {% for foo in my_from %}
        <!-- foo.errors.0 拿到错误列表的第一个错误值 -->
        <p>{{ foo.label }}:{{ foo }} <span style="color: red; font-size: 12px">{{ foo.errors.0 }}</span></p>
    {% endfor %}
    <input type="submit" value="注册">
</form>
</body>
</html>
index.html
  • 局部钩子&全局钩子
    • 局部:在类内定义一个函数,名为::clean_字段名(self),在内部取出该字段,进行校验,如果通过将该字段返回,如果失败则抛出异常(ValidationError)
    • 全局:在类中定义一个函数,clean(self)
from django.shortcuts import render
from django import forms
from django.forms import widgets
from django.core.exceptions import ValidationError


# forms 组件数据校验的功能

# 定义一个类,继承 forms.Form
class MyForm(forms.Form):
    name = forms.CharField(max_length=8, min_length=4, required=True, label='用户名',
                           error_messages={'max_length': '用户名不能多于8位字符或数字',
                                           'min_length': '用户名不能少于4位字符或数字',
                                           'required': '必填字段'},
                           widget=widgets.TextInput(attrs={'class': 'form-control'}))
    pwd = forms.CharField(max_length=11, min_length=6, required=True, label='密码',
                          error_messages={'max_length': '密码不能多于11位字符或数字',
                                          'min_length': '密码不能少于6位字符或数字',
                                          'required': '必填字段'},
                          widget=widgets.PasswordInput(attrs={'class': 'form-control'}))
    re_pwd = forms.CharField(max_length=11, min_length=6, required=True, label='确认密码',
                             error_messages={'max_length': '密码不能多于11位字符或数字',
                                             'min_length': '密码不能少于6位字符或数字',
                                             'required': '必填字段'},
                             widget=widgets.PasswordInput(attrs={'class': 'form-control'}))
    email = forms.EmailField(label='邮箱', error_messages={'required': '必填字段',
                                                         'invalid': '不符合邮箱格式'},
                             widget=widgets.EmailInput(attrs={'class': 'form-control'}))

    # 局部钩子(自定义)
    def clean_name(self):
        # self 当前的form对象
        name = self.cleaned_data.get('name')
        if name.startswith('s'):
            raise ValidationError('不能以s开头')
        else:
            return name

    # 全局钩子(自定义)
    def clean(self):
        pwd = self.cleaned_data.get('pwd')
        re_pwd = self.cleaned_data.get('re_pwd')
        if pwd == re_pwd:
            # 校验成功,返回成功的数据
            return self.cleaned_data
        else:
            # 失败,抛出异常
            raise ValidationError('两次密码不一致')

    '''
    注:
    required = True 必填字段
    max_length = 16 最大长度
    min_length = 16 最小长度
    label='用户名' 设置中文显示
    error_messages={'required': '必填字段'} 错误信息渲染
    widget = widgets.TextInput(attrs={'class': 'form-control'}) 输入框的类型及样式
    '''


def index(request):
    if request.method == 'GET':
        my_from = MyForm()
    elif request.method == 'POST':
        my_from = MyForm(request.POST)
        if my_from.is_valid():
            print(my_from.cleaned_data)
        else:
            all_error = my_from.errors.get('__all__')[0]

            print(my_from.errors.as_data)
    return render(request, 'index.html', locals())
views.py

注册功能的实现

from django.conf.urls import url
from django.contrib import admin
from form_module import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index),
]
urls.py
from django.shortcuts import render, redirect
from django import forms
from django.forms import widgets
from django.core.exceptions import ValidationError
from form_module import models

# forms 组件数据校验的功能

# 定义一个类,继承 forms.Form
class MyForm(forms.Form):
    name = forms.CharField(max_length=8, min_length=4, required=True, label='用户名',
                           error_messages={'max_length': '用户名不能多于8位字符或数字',
                                           'min_length': '用户名不能少于4位字符或数字',
                                           'required': '必填字段'},
                           widget=widgets.TextInput(attrs={'class': 'form-control'}))
    pwd = forms.CharField(max_length=11, min_length=6, required=True, label='密码',
                          error_messages={'max_length': '密码不能多于11位字符或数字',
                                          'min_length': '密码不能少于6位字符或数字',
                                          'required': '必填字段'},
                          widget=widgets.PasswordInput(attrs={'class': 'form-control'}))
    re_pwd = forms.CharField(max_length=11, min_length=6, required=True, label='确认密码',
                             error_messages={'max_length': '密码不能多于11位字符或数字',
                                             'min_length': '密码不能少于6位字符或数字',
                                             'required': '必填字段'},
                             widget=widgets.PasswordInput(attrs={'class': 'form-control'}))
    email = forms.EmailField(label='邮箱', error_messages={'required': '必填字段',
                                                         'invalid': '不符合邮箱格式'},
                             widget=widgets.EmailInput(attrs={'class': 'form-control'}))

    # 局部钩子(自定义)
    def clean_name(self):
        # self 当前的form对象
        name = self.cleaned_data.get('name')
        if name.startswith('s'):
            raise ValidationError('不能以s开头')
        else:
            return name

    # 全局钩子(自定义)
    def clean(self):
        pwd = self.cleaned_data.get('pwd')
        re_pwd = self.cleaned_data.get('re_pwd')
        if pwd == re_pwd:
            # 校验成功,返回成功的数据
            return self.cleaned_data
        else:
            # 失败,抛出异常
            raise ValidationError('两次密码不一致')

    '''
    注:
    required = True 必填字段
    max_length = 16 最大长度
    min_length = 16 最小长度
    label='用户名' 设置中文显示
    error_messages={'required': '必填字段'} 错误信息渲染
    widget = widgets.TextInput(attrs={'class': 'form-control'}) 输入框的类型及样式
    '''


def index(request):
    if request.method == 'GET':
        my_from = MyForm()
    elif request.method == 'POST':
        my_from = MyForm(request.POST)
        if my_from.is_valid():
            my_from.cleaned_data.pop('re_pwd')
            models.User.objects.create(**my_from.cleaned_data)
            return redirect('http://www.baidu.com')
            # print(my_from.cleaned_data)
        else:
            all_error = my_from.errors.get('__all__')

            # 判断是否有信息
            if all_error:
                all_error = all_error[0]
            # print(my_from.errors.as_data)
    return render(request, 'index.html', locals())
views.py
from django.db import models


# Create your models here.

class User(models.Model):
    name = models.CharField(max_length=32)
    pwd = models.CharField(max_length=64)
    email = models.EmailField()
models.py
<!DOCTYPE html>
<html lang="en">
<head>
    {% load static %}
    <meta charset="UTF-8">
    <script src="{% static 'jquery-3.3.1.min.js' %}"></script>
    <link rel="stylesheet" href="{% get_static_prefix %}bootstrap-3.3.7/css/bootstrap.min.css">
    <title>用户注册</title>
</head>
<body>
<form action="" method="post">
    {% for foo in my_from %}
        <!-- foo.errors.0 拿到错误列表的第一个错误值 -->
        <p>{{ foo.label }}:{{ foo }} <span id="msg" style="color: red; font-size: 12px">{{ foo.errors.0 }}</span></p>
    {% endfor %}
    <input type="submit" value="注册"><span id="info" style="color: red; font-size: 12px">{{ all_error }}</span>
</form>
</body>
<script>
    // 设置提示信息的定时器
    setTimeout(function () {
        $('#msg').html('')
    }, 2000);
    setTimeout(function () {
        $('#info').html('')
    }, 2000)
</script>
</html>
index.html

 

posted @ 2018-11-21 21:31  cnblogs用户  阅读(149)  评论(0编辑  收藏  举报