Django 之 Form

forms组件

1. 校验字段功能

针对一个实例:注册用户讲解。

模型:models.py

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)

 视图函数:register

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>

 

posted @ 2019-06-21 17:29  XIaoming·zhou  阅读(177)  评论(0编辑  收藏  举报