Django(十五)Form组件

Posted xiangtingshen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django(十五)Form组件相关的知识,希望对你有一定的参考价值。

https://www.cnblogs.com/haiyan123/p/7778888.html

 

Form组件

    - 对用户请求的验证
        - AJax
        - Form
    - 生成html代码

    a. 创建一个类
    b. 类中创建字段(包含正则表达式)
    c. GET
        obj = Fr()
        obj.user = > 自动生成HTML
        
    d. POST
        obj = Fr(request.POST)
        if obj.is_valid():
            obj.cleaned_data
        else:
            obj.errors
            return .... obj

 

一、Form组件介绍

Form组件可以做的几件事情:

  1、用户请求数据验证

  2、自动生成错误信息    

  3、打包用户提交的正确信息

  4、如果其中有一个错误了,其他的正确这,保留上次输入的内容

  4、自动创建input标签并可以设置样式

二、Form组件的使用

  1、创建规则

class Foo(Form): #必须继承
    username = xxx
    password = xxx
    email = xxx
注意这里的字段必须和input的name字段一致

  2、数据和规则进行匹配

先导入view.py

from django.forms import Form
from django.forms import fields
from django.forms import widgets
from django.shortcuts import render,redirect
from app01 import models
# Create your views here.
from django.forms import Form
from django.forms import fields
from django.forms import widgets
# 1、创建规则
class TeacherForm(Form):  #必须继承Form
    # 创建字段,本质上是正则表达式
    username = fields.CharField(
        required=True,     #必填字段
        error_messages={"required":"用户名不能为空!!"},  #显示中文错误提示
        widget=widgets.TextInput(attrs={"placeholder":"用户名","class":"form-control"})  #自动生成input框
       )
    password = fields.CharField(required=True, error_messages={required: 密码不能为空},
                                widget=widgets.TextInput(attrs={placeholder: 密码, class: form-control}))  # 不能为空
    email = fields.EmailField(
        required=True,
        error_messages={"required":"邮箱不能为空!!","invalid":"无效的邮箱"},
        widget=widgets.EmailInput(attrs={"placeholder": "邮箱", "class": "form-control"})  # 自动生成input框
    ) #不能为空且邮箱格式要一致

# 2、使用规则:将数据和规则进行匹配
def teacherindex(request):
    teacher_obj = models.UserInfo.objects.all()
    # print(teacher_obj)
    return render(request,"teacherindex.html",{"teacher_obj":teacher_obj})
def add(request):
    if request.method=="GET":
        form = TeacherForm()  #只是让显示一个input框
        return render(request,"add.html",{"form":form })
    else:
        form = TeacherForm(data=request.POST)
        # print(form)  #<QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]>
        if form.is_valid():# 开始验证
            # print(‘执行成功‘,form.cleaned_data)          # 所有匹配成功,字典
            # {‘username‘: ‘asd‘, ‘password‘: ‘sdf‘, ‘email‘: ‘[email protected]‘,‘ut_id‘:1}
            form.cleaned_data[ut_id] = 1  #要分的清是班主任还是讲师
            models.UserInfo.objects.all().create(**form.cleaned_data)
            return redirect("/teacherindex/")
        else:
            # print("=====?",form.errors,type(form.errors))#返回失败的结果
            # print(form.errors["username"][0])   #拿到返回失败的结果,渲染到页面
            return render(request,"add.html",{"form":form})

html

{% block right %}
    <h1>添加老师信息</h1>
    <hr>
    <form method="post" novalidate>
        {% csrf_token %}
        <p>姓名:{{ form.username }}</p>{{ form.errors.username.0 }}
        <p>密码:{{ form.password }}</p>{{ form.errors.password.0 }}
        <p>邮箱:{{ form.email }}</p>{{ form.errors.email.0 }}
        <p><input type="submit" value="提交"></p>
    </form>
{% endblock %}

如果访问视图的是一个GET 请求,它将创建一个空的表单实例并将它放置到要渲染的模板的上下文中。这是我们在第一个访问该URL 时预期发生的情况。

如果表单的提交使用POST 请求,那么视图将再次创建一个表单实例并使用请求中的数据填充它:form = NameForm(request.POST)。这叫做”绑定数据至表单“(它现在是一个绑定的表单)。

我们调用表单的is_valid()方法;如果它不为True,我们将带着这个表单返回到模板。这时表单不再为空(未绑定),所以HTML 表单将用之前提交的数据填充,然后可以根据要求编辑并改正它。

如果is_valid()True,我们将能够在cleaned_data 属性中找到所有合法的表单数据。在发送HTTP 重定向给浏览器告诉它下一步的去向之前,我们可以用这个数据来更新数据库或者做其它处理。

注意: form = TeacherForm()  #没有参数,只是一个input框

    form = TeacherForm(data=request.POST) # 数据和规则放置一起 (添加的时候用)

    form = TeacherForm(initial={‘username‘:obj.username,‘password‘:obj.password,‘email‘:obj.email})   # 显示input,并且将数据库中的默认值填写到input框中 (编辑的时候用)

 

简单实例(一)

技术图片
class F1Form(forms.Form):
    user = fields.CharField(required=True,
                            max_length=18,
                            min_length=6,
                            error_messages={required:用户名不能为空,max_length: 太长了,
                                            min_length:太短了},
                            widget=widgets.TextInput(attrs={placeholder:"用户名"})
                            )
    pwd = fields.CharField(required=True, min_length=9, error_messages={min_length: "太短了"})
    age = fields.IntegerField(required=True)
    email = fields.EmailField(required=True,min_length=8, error_messages={invalid: "格式错误"})

def f1(request):
    if request.method == GET:
        obj = F1Form()
        return render(request, f1.html, {obj: obj})
    if request.method == "POST":
        obj = F1Form(request.POST)
        if obj.is_valid():
            print("验证成功", obj.cleaned_data)
            return redirect(http://www.xiaohuar.com)
        else:
            print("验证失败", obj.errors)
            return render(request, f1.html, {"obj": obj})
views.py
技术图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/f1/" method="post" novalidate>
    {% csrf_token %}
    <p>{{ obj.user }}{{ obj.errors.user.0 }}</p>
    <p>{{ obj.pwd }}{{ obj.errors.pwd.0 }}</p>
    <p>{{ obj.age }}{{ obj.errors.age.0 }}</p>
    <p>{{ obj.email }}{{ obj.errors.email.0 }}</p>
    <input type="submit" value="提交">
</form>
</body>
</html>
html

简单实例(二)

技术图片
"""django_form URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.1/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path(‘‘, views.home, name=‘home‘)
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path(‘‘, Home.as_view(), name=‘home‘)
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path(‘blog/‘, include(‘blog.urls‘))
"""
from django.contrib import admin
from django.urls import path,re_path
from app01 import views

urlpatterns = [
    path(admin/, admin.site.urls),
    path(users/, views.users),
    path(add_user/, views.add_user),
    re_path(redit_user-(d+)/, views.edit_user),
]
urls.py
技术图片
from django.shortcuts import render, redirect
from app01 import models
from app01 import forms
# Create your views here.

def users(request):
    obj_list = models.UserInfo.objects.all()
    return render(request, "user.html", {"obj_list": obj_list})

def add_user(request):
    if request.method == "GET":
        obj = forms.UserForm()
        return render(request, "add_user.html", {"obj": obj})
    if request.method == "POST":
        obj = forms.UserForm(request.POST)
        if obj.is_valid():
            models.UserInfo.objects.create(**obj.cleaned_data)
            return redirect("/users/")
        else:
            return render(request, "add_user.html", {"obj": obj})

def edit_user(request,nid):
    if request.method == "GET":
        data = models.UserInfo.objects.filter(id=nid).first()
        obj = forms.UserForm({username: data.username,email: data.email})
        return render(request, "edit_user.html", {obj: obj, nid: nid})
    else:
        obj = forms.UserForm(request.POST)
        if obj.is_valid():
            models.UserInfo.objects.filter(id=nid).update(**obj.cleaned_data)
            return redirect("/users/")
        else:
            return render(request, edit_user.html, {obj: obj, nid: nid})
views.py
技术图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<a href="/add_user/">添加</a>

{% for item in obj_list %}
    <li>
        {{ item.id }}--{{ item.username }}--{{ item.email }}
        <a href="/edit_user-{{ item.id }}/">编辑</a>
    </li>
{% endfor %}

</body>
</html>
users.html
技术图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/add_user/" method="post" novalidate>
    {% csrf_token %}
    <p>{{ obj.username }}{{ obj.errors.username.0 }}</p>
    <p>{{ obj.email }}{{ obj.errors.email.0 }}</p>
    <input type="submit" value="提交">
</form>

</body>
</html>
add_user.html
技术图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/edit_user-{{ nid }}/" method="post" novalidate>
        {% csrf_token %}
        <p>{{ obj.username }}{{ obj.errors.username.0 }}</p>
        <p>{{ obj.email }}{{ obj.errors.email.0 }}</p>
        <input type="submit" value="提交">
    </form>
</body>
</html>
edit.html
技术图片
from django import forms as dforms
from django.forms import fields

class UserForm(dforms.Form):
    username = fields.CharField()
    email = fields.EmailField()
forms.py

 

Widgets

每个表单字段都有一个对应的Widget 类,它对应一个HTML 表单Widget,例如<input type="text">

在大部分情况下,字段都具有一个合理的默认Widget。例如,默认情况下,CharField 具有一个TextInput Widget,它在HTML 中生成一个<input type="text">

字段的数据

不管表单提交的是什么数据,一旦通过调用is_valid() 成功验证(is_valid() 返回True),验证后的表单数据将位于form.cleaned_data 字典中。这些数据已经为你转换好为Python 的类型。

注:此时,你依然可以从request.POST 中直接访问到未验证的数据,但是访问验证后的数据更好一些。

在上面的联系表单示例中,is_married将是一个布尔值。类似地,IntegerField 和FloatField 字段分别将值转换为Python 的int 和float

 

以上是关于Django(十五)Form组件的主要内容,如果未能解决你的问题,请参考以下文章

Django框架(十五)—— Django分页组件

Django 框架篇: Django中的Form 组件

Django—分页器与form组件

Django框架之Form组件

Django Form 组件

Django高级-Form表单组件应用