1. 程式人生 > >Django中的form表單

Django中的form表單

ati 錯誤信息 信息 ren creat obb init elif sel

1,手寫一個form表單提交數據

  • 有input標簽,讓用戶可以填數據
  • 校驗form表單提數據
  • 提示錯誤信息

html頁面代碼:

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <title>註冊</title>
</head>
<body>
<h1>form表單中的註冊</h1>
<form action="" method="post">
    {% csrf_token %}  {# 跨站請求偽造 #}
    <p>用戶名:
        <input type="text" name="user"><span style="color:red">{{ error_name }}</span>
    </p>
    <p>密碼:
        <input type="password" name="pwd"><span style="color:red">{{ error_pwd }}</span>
    </p>
    <input type="submit">
</form>
</body>
</html>

view業務邏輯的代碼:

from django.shortcuts import render, HttpResponse
from django import forms
# Create your views here.


class RegForm(forms.Form):
    user = forms.CharField(max_length=32)
    pwd = forms.CharField(max_length=32)


def login(request):
    # 全局定義變量的值,第一次是get請求的時候需要有值
    error_name = ""
    error_pwd = ""
    # 第二次進來是POST請求要提交數據
    if request.method == "POST":
        print(123)
        # 獲取到用戶輸入的值
        user = request.POST.get("user")
        pwd = request.POST.get("pwd")
        print(user)
        print(pwd)
        # 拿到數據後進行數據判斷
        if len(user) > 6 and len(pwd) > 6:
            # 數據符合要求,進行註冊成功的操作,這裏就先返回一個HttpResponse對象
            return HttpResponse("註冊成功")

        elif len(user) > 6 and len(pwd) < 6:
            # 用戶名大於6個字符,但是密碼小於6個字符
            error_pwd = "這個有點短~~~"
        elif len(user) < 6 and len(pwd) > 6:
            # 用戶名長度大於6,密碼小於6
            error_name = "這個有點短!!!"
        else:
            error_name = "這個有點短!!!"
            error_pwd = "這個有點短~~~"
    # 第一次進來返回一個html登錄頁面
    return render(request,
                  "register.html",
                  {"error_name": error_name, "error_pwd": error_pwd})

2,Django中的form提交數據:

forms代碼:

from django import forms
from app_form.models import User
from django.core.exceptions import ValidationError
from django.forms import widgets
from django.core.validators import RegexValidator
from app_form .models import User, Hobby
import re


# 驗證校驗輸入框的信息(自定義校驗)
def check_name(value):
    if "雪" in value:  
        raise ValidationError("你這個不是來自於日 本")
    
    
# 定義form類繼承forms.Form(必須繼承)
class RegForm(forms.Form):
    # 指定類裏邊屬性的類型字符串不超過32個字符
    user = forms.CharField(
        label="用戶名",  # 在生成input標簽的時候會顯示用戶名這幾個字
        max_length=12,  # 用戶名這個輸入框的最大長度不超過32個字符
        min_length=6,  # 用戶名這個輸入框的最想長度不小於6個字符
        required=True,  # 表示這個輸入框必須填的結果是False,也就是說可以為空
        initial="雪雪",  # initial的翻譯是最初的,最開始的,也就是說輸入框的第一次訪問是指定的值"雪雪"
        disabled=False,  # disable翻譯是禁用,表示這個輸入框禁用的性質是False,表示可以輸入值
        validators=[check_name],  # 翻譯的意思是驗證,也就是將用戶輸入的值傳給check_name這個函數去校驗
        error_messages={
            "min_length": "你這也太短了...,還不到6",
            "required": "不能為空"
        }
    )
    # 指定類裏邊的密碼屬性的字符串不差過32個字符
    pwd = forms.CharField(
        max_length=12,  # 密碼的最大長度不超過12個字符
        min_length=6,  # 密碼的最小長度不少於6個字符
        label="密碼",  # 在生成input框的時候會說明 是這個輸入框的的作用
        error_messages={
            "min_length": "你這也忒短了吧",
            "max_length": "你這太長了,都受不了了...",
            "required": "不能為空"
        }
    )

    gender = forms.ChoiceField(
        choices=((1, "男"), (2, "女"), (3, "不詳")),  # 單選框只能選一個框
        widget=widgets.RadioSelect(),
        label="性別"

    )

    hobby = forms.ChoiceField(
        choices=((1, "足球"), (2, "籃球"), (3, "雙色球")),
        widget=widgets.CheckboxSelectMultiple,
        label="愛好"
    )

    phone = forms.CharField(
        label="手機號",
        validators=[
            RegexValidator(r"^1[3-9]\d{9}$", "手機號不正經")  # 模式:RegexValidator(正則匹配表達式, 錯誤信息)
        ]
    )

    # pwd = forms.CharField(
    #     label="密碼",
    #     min_length=6,
    #     max_length=12,
    #     widget=widgets.PasswordInput()
    # )

    re_ped = forms.CharField(
        label="確認密碼",
        min_length=6,
        max_length=12,
        widget=widgets.PasswordInput()

    )
    

Html代碼:

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <title>高逼格的註冊</title>
</head>
<body>
<form action="" method="post" novalidate>
    {% csrf_token %}
{#    {{ form_obj.as_p }}#}
{#    <input type="submit">#}
    <p>
        {{ form_obj.user.label }}
        {{ form_obj.user }}
        <span style="color: red;">{{ form_obj.user.errors.0 }}</span>
        <div>{{ form_obj.user.errors.1 }}</div>
        <div>{{ form_obj.user.errors.2 }}</div>
    </p>
    <p>
        {{ form_obj.pwd.label }}
        {{ form_obj.pwd}}
        <span style="color: red">{{ form_obj.pwd.errors.0 }}</span>
    </p>
    <hr>
    <p>

        {{ form_obj.gender.lable }}
        {{ form_obj.gender }}
    </p>
    <p>
        {{ form_obj.hobby.label }}
        {{ form_obj.hobby }}
    </p>
    <p>
        {{ form_obj.phone.label }}
        {{ form_obj.phone }}
    </p>
    <p>
        {{ form_obj.pwd.label }}
        {{ form_obj.pwd }}
    </p>
    {{ form_obj.errors }}
    <input type="submit">
</form>
</body>
</html>

業務邏輯代碼:

def register(request):
    form_obj = RegForm()  # 實例化一個form中RegForm的對象就能拿到關於RegForm的屬性和方法
    print("第一次實例化的對象:",form_obj,type(form_obj))

    if request.method == "POST":
        # 重新實例化一個RegForm的對象,可以拿到RegForm的所有的屬性和方法
        form_obj = RegForm(request.POST)
        print("第二次實例化的對象:",form_obj,type(form_obj))
        print("錯誤信息:", form_obj.errors,type(form_obj.errors))
        for k, v in form_obj.errors.items():
            print(k, v)
        if form_obj.is_valid():
            # cleaned_data 是經過校驗的數據
            print(form_obj.cleaned_data)  # 拿到的是一個{‘user‘: ‘天王蓋地虎,小米一米五‘, ‘pwd‘: ‘123‘}字典
            print(form_obj.cleaned_data["user"])
            print(form_obj.cleaned_data["pwd"])
            # 表示註冊成功,可以享受提供的"服務"
            # 咱們先返回一個註冊成功的頁面表示註冊成功進行的操作
            return HttpResponse("註冊成功")
    # 一次訪問是一個get請求,返回一個html頁面
    return render(request, "register2.html", {"form_obj":form_obj})

技術分享圖片

3鉤子函數

3.1>局部鉤子函數代碼:

    # 局部鉤子函數,只是校驗某一個字段的校驗

    def clean_phone(self):
        # self指的是校驗誰就是誰,clean_data是通過瀏覽器校驗後拿出來的字典
        value = self.cleaned_data.get("phone")
        # 拿到用戶輸入的數據後進行正則匹配
        if re.match(r‘1[3-9]\d{9}‘, value):  # match(正則表達式, 要匹配的字符串)
            return value  # 當手機號匹配成功,是一個合法的手機號,就返回這個手機號
        # 當匹配不成功就拋異常
        raise ValidationError("手機號不正經")

    def clean_re_ped(self):
        # 獲取用戶輸入的密碼們
        pwd = self.cleaned_data.get("pwd")
        re_pwd = self.cleaned_data.get("re_pwd")
        # 判斷兩次輸入的密碼是否一致
        if pwd == re_pwd:
            # 當兩次結果一致時,返回這個數據的字典
            return self.cleaned_data
        # 當pwd不等於re_pwd時拋一個異常返回給瀏覽器
        raise ValidationError("兩次密碼不一致")

3.2>全局鉤子函數代碼:

  # 全局鉤子函數

    def clean(self):
        # 全局鉤子就是在forms裏的所有字段都可以拿過來校驗
        # 獲取兩次輸入的密碼來做校驗
        pwd = self.cleaned_data.get("pwd")
        re_pwd = self.cleaned_data.get("re_pwd")
        # 判斷兩次結果是否正確
        if pwd == re_pwd:
            return self.cleaned_data
        # 增加錯誤信息
        self.add_error("re_pwd", "兩次校驗結果不一致")
        raise ValidationError("兩次校驗結果不一致")

小結:form組件的主要功能:

  • 生成頁面可用的標簽
  • 對用戶提交的數據進行校驗
  • 保留上次輸入的內容

Django中的form表單