Form表單——例子

Form

Form的驗證思路html

前端:form表單前端

後臺:建立form類,當請求到來時,先匹配,匹配出正確和錯誤信息。python

Django的Form驗證實例mysql

建立project,進行基礎配置文件配置git

STATIC_URL = '/static/'
STATICFILES_DIRS = (
    os.path.join(BASE_DIR,"static"),
)
settings.py

 

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
settings.py之csrf註銷

 

import pymysql
pymysql.install_as_MySQLdb()
__init__.py

 

from django.conf.urls import url
from django.contrib import admin
from app01.views import account

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^form1/', account.form1),
    # url(r'^test/', account.test),
]
urls.py

 

views.account.py:正則表達式

複製代碼
from django.shortcuts import render,HttpResponse
from app01.forms import Form1

def form1(request):
    if request.method=="POST":  #這裏POST必定要大寫
        #一般獲取請求信息
        #request.POST.get("user",None)
        #request.POST.get("pwd",None)
        #獲取請求內容,作驗證
        f = Form1(request.POST)  #request.POST:將接收到的數據經過Form1驗證
        if f.is_valid():  #驗證請求的內容和Form1裏面的是否驗證經過。經過是True,不然False。
            print(f.cleaned_data)  #cleaned_data類型是字典,裏面是提交成功後的信息
        else:  #錯誤信息包含是否爲空,或者符合正則表達式的規則
            print(type(f.errors),f.errors)  #errors類型是ErrorDict,裏面是ul,li標籤
            return render(request,"account/form1.html",{"error":f.errors})
    return render(request,"account/form1.html")
複製代碼

 

html:sql

複製代碼
<body>
{#{{ error }}接收後臺返回的錯誤信息封裝在ul,li標籤裏面:#}
    {{ error }}
    <form action="/form1/" method="POST">
        <div>
            <input type="text" name="user" />
        </div>
        <div>
            <input type="text" name="pwd" />
        </div>
        <div>
            <input type="submit" value="提交" />
        </div>
    </form>
</body>
複製代碼

 

forms.py:數據庫

from django import forms

class Form1(forms.Form):
    user = forms.CharField()
    pwd = forms.CharField()

 

訪問頁面:django

沒有輸入內容後提交,經過模板語言展現了錯誤信息json

 

Django強大之form驗證時不用自定義錯誤信息就能夠返回錯誤信息到前端以標籤方式展示。

.is_valid():返回True或者False

.cleaned_data:經過驗證後的數據

errors:
.error.get("user",None)error封裝全部的錯誤信息,若是沒有獲取到,默認爲None。

如:

 

.error.get["pwd"]直接獲取到ul、li。

如:

 

 

 Form之精華版本

forms.py

from django import forms

class Form1(forms.Form):
    user = forms.CharField()
    pwd = forms.CharField()

 

HTML:

複製代碼
   <form action="/form1/" method="POST">
        <div class="input-group">
            {#接收後臺傳過來的form對象,自動生成input標籤#}
            {{ form.user }}
            {#從後臺傳過來的error是字典,直接{{ error.user.0 }}呈現錯誤信息#}
       {#若是後臺返回了錯誤信息,將錯誤信息放入span標籤,在頁面顯示,不然不顯示#}
            {% if error.user.0 %}
            <span>{{ error.user.0 }}</span>
            {% endif %}
        </div>
        <div class="input-group">
            {{ form.pwd }}
            {% if error.pwd.0 %}
            <span>{{ error.pwd.0 }}</span>
            {% endif %}
        </div>
        <div>
            <input type="submit" value="提交" />
        </div>
    </form>
複製代碼

 

account.py

複製代碼
def form1(request):
    if request.method == "POST":
        f = Form1(request.POST)
        if f.is_valid():
            print(f.cleaned_data)
        else:
            return render(request,"account/form1.html",{"error":f.errors,"form":f})
    else:
        # 若是不是post提交數據,就不傳參數建立對象,並將對象返回給前臺,直接生成input標籤,內容爲空
        f = Form1()
        return render(request,"account/form1.html",{"form":f})
    return render(request,"account/form1.html")
複製代碼

注:

 

 頁面展現:

注:這裏的input標籤是後端返回form對象到前端經過{{ form.xxx }}所建立的

 

更強大的功能:

 forms裏面的字段:

複製代碼
required:是否能夠爲空。required=True 不能夠爲空,required=False 能夠爲空
max_length=4 最多4個值,超過不會顯示
min_length=2 至少兩個值,少於兩個會返回提示信息
error_messages={'required': '郵箱不能爲空', 'invalid': '郵箱格式錯誤'}  自定義錯誤信息,invalid 是格式錯誤
widget=forms.TextInput(attrs={'class': 'c1'}) 給自動生成的input標籤自定義class屬性
widget=forms.Textarea()  生成Textarea標籤。widget默認生成input標籤
複製代碼

實戰:

models.py

複製代碼
from django.db import models

# Create your models here.
class Author(models.Model):
    """
    做者
    """
    name = models.CharField(max_length=100)
    age = models.IntegerField()

class BookType(models.Model):
    """
    圖書類型
    """
    caption = models.CharField(max_length=64)

class Book(models.Model):
    """
    圖書
    """
    name = models.CharField(max_length=64)
    pages = models.IntegerField()
    price = models.DecimalField(max_digits=10,decimal_places=2)
    pubdate = models.DateField()

    authors = models.ManyToManyField(Author)
    book_type = models.ForeignKey(BookType)
複製代碼

 

forms.py:

複製代碼
from django import forms
from app01 import models

class Form1(forms.Form):
    user = forms.CharField(
        widget=forms.TextInput(attrs={'class': 'c1'}),
        error_messages={'required': '用戶名不能爲空'}, )
    pwd = forms.CharField(max_length=4, min_length=2,required=True)
    email = forms.EmailField(error_messages={'required': '郵箱不能爲空', 'invalid': '郵箱格式錯誤'})

    memo = forms.CharField(
        widget=forms.Textarea()
    )
    #直接寫數據
    # user_type_choice = (
    #     (0, '普通用戶'),
    #     (1, '高級用戶'),
    # )
    #經過BookType表查詢信息,values_list拿到的是元組。id做爲value顯示,caption做爲text在頁面顯示
    # user_type_choice = models.BookType.objects.values_list('id', 'caption')
    # book_type = forms.CharField(
    #     widget=forms.widgets.Select(choices=user_type_choice, attrs={'class': "form-control"}))

    
    #寫上如下代碼就不用擔憂數據庫添加了數據而不能及時獲取了
    def __init__(self, *args, **kwargs):
        #每次建立Form1對象時執行init方法
        super(Form1, self).__init__(*args, **kwargs)

        self.fields['book_type'] = forms.CharField(
            widget=forms.widgets.Select(choices=models.BookType.objects.values_list('id', 'caption'),
                                        attrs={'class': "form-control"}))
複製代碼

 

HTML:

複製代碼
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .input-group{
            position: relative;
            padding: 20px;
            width: 250px;
        }
        .input-group input{
            width: 200px;
            display: inline-block;
        }
        .inline-group span{
            display: inline-block;
            position: absolute;
            height: 12px;
            font-size: 8px;
            border: 1px solid red;
            background-color: coral;
            color: white;
            top: 41px;
            left: 20px;
            width: 202px;
        }
    </style>
</head>
<body>
    <form action="/form1/" method="POST">
        <div class="input-group">
{#            接收後臺傳過來的form對象,自動生成input標籤#}
            {{ form.user }}
{#            從後臺傳過來的error是字典,直接{{ error.user.0 }}呈現錯誤信息#}
{#            若是後臺返回了錯誤信息,將錯誤信息放入span標籤,在頁面顯示,不然不顯示#}
            {% if error.user.0 %}
            <span>{{ error.user.0 }}</span>
            {% endif %}
        </div>
        <div class="input-group">
            {{ form.pwd }}
            {% if error.pwd.0 %}
            <span>{{ error.pwd.0 }}</span>
            {% endif %}
        </div>
        <div class="input-group">
            {{ form.email }}
            {% if error.email.0 %}
            <span>{{ error.email.0 }}</span>
            {% endif %}
        </div>
         <div class="input-group">
            {{ form.memo }}
            {% if error.memo.0 %}
            <span>{{ error.memo.0 }}</span>
            {% endif %}
        </div>
             <div class="input-group">
            {{ form.book_type }}
            {% if error.book_type.0 %}
            <span>{{ error.book_type.0 }}</span>
            {% endif %}
        </div>

        <div>
            <input type="submit" value="提交" />
        </div>
    </form>

</body>
</html>
複製代碼

 

account.py:

複製代碼
from django.shortcuts import render,HttpResponse
from app01.forms import Form1
from app01.models import *


# def test(req):
#     BookType.objects.create(caption='技術')
#     BookType.objects.create(caption='文學')
#     BookType.objects.create(caption='動漫')
#     BookType.objects.create(caption='男人裝')
#     return HttpResponse("ok")


def form1(request):
    if request.method == "POST":
        f = Form1(request.POST)
        if f.is_valid():
            print(f.cleaned_data)
        else:
            return render(request,"account/form1.html",{"error":f.errors,"form":f})
    else:
        # 若是不是post提交數據,就不傳參數建立對象,並將對象返回給前臺,直接生成input標籤,內容爲空
        f = Form1()
        return render(request,"account/form1.html",{"form":f})
    return render(request,"account/form1.html")
複製代碼

 

Django裏面沒有手機驗證,沒有的須要自定義

示例:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re
from django import forms
from django.core.exceptions import ValidationError


def mobile_validate(value):
    mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
    if not mobile_re.match(value):
        raise ValidationError('手機號碼格式錯誤')


class PublishForm(forms.Form):

    user_type_choice = (
        (0, u'普通用戶'),
        (1, u'高級用戶'),
    )

    user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice,
                                                                  attrs={'class': "form-control"}))

    title = forms.CharField(max_length=20,
                            min_length=5,
                            error_messages={'required': u'標題不能爲空',
                                            'min_length': u'標題最少爲5個字符',
                                            'max_length': u'標題最多爲20個字符'},
                            widget=forms.TextInput(attrs={'class': "form-control",
                                                          'placeholder': u'標題5-20個字符'}))

    memo = forms.CharField(required=False,
                           max_length=256,
                           widget=forms.widgets.Textarea(attrs={'class': "form-control no-radius", 'placeholder': u'詳細描述', 'rows': 3}))

    phone = forms.CharField(validators=[mobile_validate, ],
                            error_messages={'required': u'手機不能爲空'},
                            widget=forms.TextInput(attrs={'class': "form-control",
                                                          'placeholder': u'手機號碼'}))

    email = forms.EmailField(required=False,
                            error_messages={'required': u'郵箱不能爲空','invalid': u'郵箱格式錯誤'},
                            widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': u'郵箱'}))
Form
def publish(request):
    ret = {'status': False, 'data': '', 'error': '', 'summary': ''}
    if request.method == 'POST':
        request_form = PublishForm(request.POST)
        if request_form.is_valid():
            request_dict = request_form.clean()
            print request_dict
            ret['status'] = True
        else:
            error_msg = request_form.errors.as_json()
            ret['error'] = json.loads(error_msg)
    return HttpResponse(json.dumps(ret))
View
相關文章
相關標籤/搜索