Django 之 Form

forms組件

1. 校驗字段功能

針對一個實例:註冊用戶講解。css

模型:models.pyhtml

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)

 視圖函數:registerpython

from django.forms import widgets
from django.core.exceptions import ValidationError

wid_01 = widgets.TextInput(attrs={"class": "form-control"})  #用了bootstrap,因此加個樣式屬性
wid_02 = widgets.PasswordInput(attrs={"class": "form-control"}) #注意!! 在校驗失敗後,form對象不保存PasswordInput的value值,因此頁面要從新輸入


class UserForm(forms.Form):
    name = forms.CharField(min_length=3, label="用戶名", error_messages={"required": "該字段不能爲空", "min_length": "最小長度爲3"},
                           widget=wid_01
                           )
    pwd = forms.CharField(min_length=4, label="密碼",
                          widget=wid_02
                          )
    r_pwd = forms.CharField(min_length=4, label="確認密碼", error_messages={"required": "該字段不能爲空"},
                            widget=wid_02)
    email = forms.EmailField(label="郵箱", error_messages={"required": "該字段不能爲空", "invalid": "格式錯誤"},
                             widget=wid_01)
    tel = forms.CharField(label="手機號", widget=wid_01)


def register(request):
    if request.method == "POST":

        print(request.POST)

        # form=UserForm({"name":"yu","email":"123@qq.com","xxxx":"alex"})

        form = UserForm(request.POST)  # form表單的name屬性值應該與forms組件字段名稱一致

        print(form.is_valid())  # 返回布爾值

        if form.is_valid():
            print(form.cleaned_data)  # {"name":"yuan","email":"123@qq.com"}
        else:
            print(form.cleaned_data)  # {"email":"123@qq.com"}
            # print(form.errors)        # {"name":[".........."]}
            # print(type(form.errors))  # ErrorDict : {"校驗錯誤的字段":["錯誤信息",]}
            # print(form.errors.get("name"))
            # print(type(form.errors.get("name")))    # ErrorList ["錯誤信息",]
            # print(form.errors.get("name")[0])

            return render(request, "register.html", locals())

        '''

        form.is_valid()   :返回布爾值
        form.cleaned_data :{"name":"yuan","email":"123@qq.com"}
        form.errors       :{"name":[".........."]}

        '''

    form = UserForm()

    return render(request, "register.html", locals())

2. 渲染標籤功能 

2.1 渲染方式1

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
   <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<h3>註冊頁面</h3>
<div class="container">
    <div class="row">
        <div class="col-md-6 col-lg-offset-3">

                <form action="" method="post">
                    {% csrf_token %}
                    <div>
                        <label for="">用戶名</label>
                        {{ form.name }}
                    </div>
                    <div>
                        <label for="">密碼</label>
                        {{ form.pwd }}
                    </div>
                    <div>
                        <label for="">確認密碼</label>
                        {{ form.r_pwd }}
                    </div>
                    <div>
                        <label for=""> 郵箱</label>
                        {{ form.email }}
                    </div>

                    <input type="submit" class="btn btn-default pull-right">
                </form>
        </div>
    </div>
</div>



</body>
</html>

2.2 渲染方式2

<form action="" method="post">
                    {% csrf_token %}
                    
                    {% for field in form %}
                        <div>
                            <label for="">{{ field.label }}</label>
                            {{ field }}
                        </div>
                    {% endfor %}
                    <input type="submit" class="btn btn-default pull-right">
                
</form>

2.3 渲染方式3

<form action="" method="post">
    {% csrf_token %}
    
    {{ form.as_p }}
    <input type="submit" class="btn btn-default pull-right">

</form>

3. 顯示錯誤與重置輸入信息功能

視圖

def register(request):

    if request.method=="POST":
        form=UserForm(request.POST)
        if form.is_valid():
            print(form.cleaned_data)       # 全部乾淨的字段以及對應的值
        else:
            print(form.cleaned_data)       #
            print(form.errors)             # ErrorDict : {"校驗錯誤的字段":["錯誤信息",]}
            print(form.errors.get("name")) # ErrorList ["錯誤信息",]
        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">{{ field.errors.0 }}</span>
        </div>
    {% endfor %}
    <input type="submit" class="btn btn-default">

</form>

4. 局部鉤子與全局鉤子

視圖

# forms組件
from django import forms
from django.core.exceptions import ValidationError


class UserForm(forms.Form):
    username = forms.CharField(min_length=3, max_length=6, label="用戶名",
                               error_messages={"required": "該字段不能爲空", "min_length": "最小長度爲3", "max_length": "最大長度爲6"}, )
    password = forms.CharField(max_length=32, label="密碼", error_messages={"required": "該字段不能爲空"})
    r_pwd = forms.CharField(max_length=32, label="確認密碼", error_messages={"required": "該字段不能爲空"})
    email = forms.EmailField(label="郵箱", error_messages={"required": "該字段不能爲空", "invalid": "格式錯誤"})
    phone = forms.CharField(max_length=32, label="手機號")

    def __init__(self, *args, **kwargs):  # 給每一個標籤添加屬性
        super().__init__(*args, **kwargs)
        for field in self.fields.values():
            field.widget.attrs['class'] = 'form-control'

    # 局部鉤子
    def clean_username(self):
        val = self.cleaned_data.get("username")
        if not val.isdigit():
            return val
        else:
            raise ValidationError("用戶名不能是純數字!")

    # 全局鉤子

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

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



def register(request):
    form = UserForm()
    if request.method == "POST":
        form = UserForm(request.POST)
        if form.is_valid():
            print(form.cleaned_data)
            user = UserInfo.objects.create_user(username=request.POST.get("username"),
                                                password=request.POST.get("password"), phone=request.POST.get("phone"),
                                                email=request.POST.get("email"))
            return redirect("/blog/login/")
        else:
            errors = form.errors.get("__all__")
            return render(request, "register.html", locals())
    return render(request, "register.html", locals())

模板

<form action="" method="post">
      {% csrf_token %}
    <p>{{ form.username.label }}
        {{ form.username }} <span class="pull-right error">{{ form.username.errors.0 }}</span>
    </p>
    <p>{{ form.password.label }}
        {{ form.password }} <span class="pull-right error">{{ form.password.errors.0 }}</span>
    </p>
    <p>{{ form.r_pwd.label }}
        {{ form.r_pwd }} <span class="pull-right error">{{ form.r_pwd.errors.0 }}</span>
                         <span class="pull-right error">{{ errors.0 }}</span>
    </p>
    <p>{{ form.email.label }}
        {{ form.email }}<span class="pull-right error">{{ form.email.errors.0 }}</span></p>
    <p>{{ form.phone.label }}
        {{ form.phone }} <span class="pull-right error">{{ form.phone.errors.0 }}</span></p>
    <button type="submit" class="btn btn-success">提交註冊</button>
</form>
相關文章
相關標籤/搜索