博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
django之Form表单
阅读量:6465 次
发布时间:2019-06-23

本文共 14589 字,大约阅读时间需要 48 分钟。

HTML表单

在HTML中,表单是<form>...</form> 之间元素的集合,它们允许访问者输入文本、选择选项、操作对象和控制等等,然后将信息发送回服务器。

某些表单的元素 —— 文本输入和复选框 —— 非常简单而且内建于HTML 本身。其它的表单会复杂些;例如弹出一个日期选择对话框的界面、允许你移动滚动条的界面、使用JavaScript 和CSS 以及HTML 表单<input> 元素来实现操作控制的界面。与<input> 元素一样,一个表单必须指定两样东西:

  1. 目的地:响应用户输入数据的URL
  2. 方式:发送数据所使用的HTTP 方法

例如,Django Admin 站点的登录表单包含几个<input> 元素:type="text" 用于用户名,type="password" 用于密码,type="submit" 用于“Log in" 按钮。它还包含一些用户看不到的隐藏的文本字段,Django 使用它们来决定下一步的行为。

它还告诉浏览器表单数据应该发往<form> 的action 属性指定的URL —— /admin/,而且应该使用method 属性指定的HTTP 方法 —— post。

当触发<input type="submit" value="Log in"> 元素时,数据将发送给/admin/。

Django 中的表单

Django 的Form 类

表单系统的核心部分是Django 的Form 类。Django 的模型描述一个对象的逻辑结构、行为以及展现给我们的方式,与此类似,Form 类描述一个表单并决定它如何工作和展现。

就像模型类的属性映射到数据库的字段一样,表单类的字段会映射到HTML 的<input>表单的元素。

表单字段在浏览器中呈现给用户的是一个HTML 的“widget” —— 用户界面的一个片段。每个字段类型都有一个合适的默认Widget 类,需要时可以覆盖。

 

widget 部件

实例化、处理和渲染表单

在Django 中渲染一个对象时,我们通常:

  1. 在视图中获得它(例如,从数据库中获取)
  2. 将它传递给模板上下文
  3. 使用模板变量将它扩展为HTML 标记

在模板中渲染表单和渲染其它类型的对象几乎一样,除了几个关键的差别。

 

构建一个表单

在html里构建这里就不写了

1.在app下面新建一个存放Forn类的文件

例如:myforms.py

  

#!/usr/bin/env python#-*- coding:utf-8 -*-from django import formsfrom django.forms import  fieldsclass UserForm(forms.Form):    user = fields.CharField(        max_length=18,        min_length=6,        required = True,        error_messages={            'required':'用户输入为空',            'max_length':'用户输入太长了',             'min_length':'用户输入太短了'        })    #自定义错误显示信息    pwd = fields.CharField(required=True,min_length=8)    age = fields.IntegerField(required=True)    email = fields.EmailField(required=True,min_length=8,                              error_messages={                                  'invalid':"用户输入格式错误,只要是格式错误都用invalid"                              })

  

  

注:它不包含 <form> 标签和提交按钮。我们必须自己在模板中提供它们。

要操作一个通过URL发布的表单,我们要在视图中实例表单。

2.views.py

from django.shortcuts import renderfrom django.shortcuts import redirectfrom app01.myfoms import UserForm# Create your views here.def users(request):    if request.method == "GET":        obj = UserForm()  #这就相当于自动生成了一个html        return render(request,'fm.html',{'obj':obj})    elif request.method == 'POST':        fo = UserForm(request.POST)        # print(fo)  #前端提交过来的数据        v = fo.is_valid()  # 判断发过来的数据验证是否通过        if v:            print(fo.cleaned_data)  # 查看用户提交的数据            return redirect('http://www.baidu.com')  # 成功验证跳转到百度        else:            print(fo.errors)  # 查看相应提交数据的错误信息            return render(request, 'fm.html', {"obj": fo})    return render(request, 'fm.html')

  

3.url

from django.conf.urls import urlfrom django.contrib import adminfrom app01 import viewsurlpatterns = [    url(r'^admin/', admin.site.urls),    url(r'^users/$', views.users),]

  

4.模板html

    
Title

{

{ obj.user }}{
{ obj.errors.user.0 }}

{

{ obj.pwd }}{
{ obj.errors.pwd.0 }}

{

{ obj.age }}{
{ obj.errors.age.0 }}

{

{ obj.email }}{
{ obj.errors.email.0 }}

/* obj.error.user.0 是显示在输入框后显示错误的显示信息 */

  

提示:

form类实例化的方法和属性is_valid() 方法     判断表单提交是否合法的数据结构,返回True/Falsecleaned_data    属性中找到所有合法的表单数据  转换好为Python 的字典类型。

 

 

 

使用表单模板

 

例如:

1新建一个表单的py文件 例如:myForms.py  在app下面新建表单内容,

内容如下

#!/usr/bin/env python#-*- coding:utf-8 -*-from django import formsfrom django.forms import  fieldsclass UserInfo(forms.Form):    user = fields.CharField()    age = fields.IntegerField()

  

2.视图views.py

from django.shortcuts import renderfrom app01 import  myForms# Create your views here.def index(request):    form = myForms.UserInfo()    if request.method == 'GET':        return render(request,'index.html',{'form':form})

  

3.路由urls.py

from django.conf.urls import urlfrom django.contrib import adminfrom app01 import  viewsurlpatterns = [    url(r'^admin/', admin.site.urls),    url(r'^index/', views.index),]

  

4.模板html

通过视图把fom表单渲染到模板的html

    
Title
{
{ form.as_table }}
{
{ form.as_p }}
    {
    { form.as_ul }}

  

上面用了几个表单渲染,form.as_p  和 forms.as_ul  和 forms.as_table

表单渲染选项

表单模板的额外标签

不要忘记,表单的输出不 包含<form> 标签,和表单的submit 按钮
对于<label>/<input> 对,还有几个输出选项:

 

  1. {
    { form.as_table }} 以表格的形式将它们渲染在<tr> 标签中
  2. {
    { form.as_p }} 将它们渲染在<p> 标签中
  3. {
    { form.as_ul }} 将它们渲染在<li> 标签中

注意,你必须自己提供<table> 或<ul> 元素。

 表单字段详解

在django的form表单api,每个字段都是一个类,所有的字段都继承Field这个类。

提示:多看源码

Field这个类的常用参数

Field    required=True,               是否允许为空    widget=None,                 HTML插件  注:重点    label=None,                  用于生成Label标签或显示内容  类似HTML的label的标签    initial=None,                初始值	  ( 类似html的input框的value值)    help_text='',                帮助信息(在标签旁边显示)    error_messages=None,         错误信息 {'required': '不能为空', 'invalid': '格式错误'}    show_hidden_initial=False,   是否在当前插件后面再加一个隐藏的且具有默认值的插件(可用于检验两次输入是否一直)    validators=[],               自定义验证规则    localize=False,              是否支持本地化    disabled=False,              是否可以编辑    label_suffix=None            Label内容后缀

  

常用字段

ChoiceField   选择类型的字段(例如,下拉框,等等)	choice[(1,'北京'),(2,'上海'),(3,'深圳')]   这个选项是提供下拉框的内容		表单模板的额外标签	不要忘记,表单的输出不 包含
标签,和表单的submit 按钮 对于

  

重点form字段

Form重点:    - 字段        用于保存正则表达式        ChoiceField *****        MultipleChoiceField        CharField        IntegerField        DecimalField        DateField        DateTimeField        EmailField        GenericIPAddressField        FileField                RegexField

  

表单字段的HTML插件

所有Field字段本质上封装了两个东西,一个是正则表达式,一个是HTML插件

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

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

 

Django内置插件

TextInput(Input)NumberInput(TextInput)EmailInput(TextInput)URLInput(TextInput)PasswordInput(TextInput)HiddenInput(TextInput)Textarea(Widget)DateInput(DateTimeBaseInput)DateTimeInput(DateTimeBaseInput)TimeInput(DateTimeBaseInput)CheckboxInputSelectNullBooleanSelectSelectMultipleRadioSelectCheckboxSelectMultipleFileInputClearableFileInputMultipleHiddenInputSplitDateTimeWidgetSplitHiddenDateTimeWidgetSelectDateWidget

  

常用widget的选择HTML插件

 不要将Widget 与表单字段搞混淆。表单字段负责验证输入并直接在模板中使用。Widget 负责渲染网页上HTML 表单的输入元素和提取提交的原始数据。但是,Widget 需要赋值给表单字段。

 

# 单radio,值为字符串  widgets方式# user = fields.CharField(#     initial=2,#     widget=widgets.RadioSelect(choices=((1,'上海'),(2,'北京'),))# ) # 单radio,值为字符串    ChoiceField选择字段方式# user = fields.ChoiceField(#     choices=((1, '上海'), (2, '北京'),),#     initial=2,#     widget=widgets.RadioSelect# ) # 单select,值为字符串# user = fields.CharField(#     initial=2,#     widget=widgets.Select(choices=((1,'上海'),(2,'北京'),))# ) # 单select,值为字符串# user = fields.ChoiceField(#     choices=((1, '上海'), (2, '北京'),),#     initial=2,#     widget=widgets.Select# ) # 多选select,值为列表# user = fields.MultipleChoiceField(#     choices=((1,'上海'),(2,'北京'),),#     initial=[1,],#     widget=widgets.SelectMultiple# )  # 单checkbox# user = fields.CharField(#     widget=widgets.CheckboxInput()# )  # 多选checkbox,值为列表# user = fields.MultipleChoiceField(#     initial=[2, ],#     choices=((1, '上海'), (2, '北京'),),#     widget=widgets.CheckboxSelectMultiple# )

  

提示:根据自已喜好,选择用widget插件,还是ChoiceField方式

 widget只能生成form相关的html标签,不能生成div,span标签等等。。。。

数据实时更新

方式一:(推荐)

在使用选择标签时,需要注意choices的选项可以从数据库中获取,但是由于是类属性字段 ***获取的值无法实时更新***,

那么需要自定义构造方法(__init__)从而达到此目的。

 

from django.forms import Formfrom django.forms import widgetsfrom django.forms import fieldsclass MyForm(Form):     user = fields.ChoiceField(        # choices=((1, '上海'), (2, '北京'),),        initial=2,        widget=widgets.Select    )     def __init__(self, *args, **kwargs):        super(MyForm,self).__init__(*args, **kwargs)        # self.fields['user'].widget.choices = ((1, '上海'), (2, '北京'),)        # 或        self.fields['user'].widget.choices = models.Classes.objects.all().value_list('id','caption')

  

 

方式二:

依赖数据库的model的__str__方法 

from django import formsfrom django.forms import fieldsfrom django.forms import widgetsfrom django.forms.models import ModelChoiceField class FInfo(forms.Form):    authors = form_model.ModelMultipleChoiceField(queryset=models.NNewType.objects.all())    # authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all())    to_field_name='id'  #使用id的那列字段作为input框的value值

  

 FORM自定制匹配正则表达式的扩展

方式一

  

from django.forms import Formfrom django.forms import widgetsfrom django.forms import fieldsfrom django.core.validators import RegexValidator                 class MyForm(Form):       user = fields.CharField(       error_messages={'invalid': '...'},       validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],                    )

  

字段下的validator

validators=[RegexValidator(r'^[0-9]+$', '请输入数字')]

validators 自定义匹配正则表达式,可以有多个匹配的正则表达式,匹配顺序是从前到后
RegexValidator这个类有两个参数,第一个是正则表达式,第二个错误提示

 

方式二

from django.forms import Formfrom django.forms import widgetsfrom django.forms import fieldsfrom django.core.validators import RegexValidator                 class MyForm(Form):      user = fields.RegexField(r'^[0-9]+$',error_messages={'invalid': '...'})

  

正则字段

 

基于源码流程的扩展

如果某一个字段不仅只是自定义正则表达式匹配,例如:还有一些用户注册的唯一性等等要求,这时候就要基于form源码来扩展

单子段验证

重写:clean_字段名方法

from django import formsfrom django.forms import fieldsfrom django.forms import widgetsfrom django.core.exceptions import NON_FIELD_ERRORS, ValidationErrorclass AForm(forms.Form):       username = fields.CharField()       user_id = fields.IntegerField(                    widget=widgets.Select(choices=[(0,'张三'),(1,'李四'),(2,'老王'),])                )            # 自定义方法 clean_字段名            # 必须返回值self.cleaned_data['username']            # 如果出错:raise ValidationError('用户名已存在')       def clean_username(self):                v = self.cleaned_data['username']                if models.UserInfo.objects.filter(username=v).count():                    # 整体错了                    # 自己详细错误信息                    raise ValidationError('用户名已存在')                return v       def clean_user_id(self):               return self.cleaned_data['user_id']

  

整体错误验证

自定义clean方法

class AForm(forms.Form):                username = fields.CharField()                user_id = fields.IntegerField(                    widget=widgets.Select(choices=[(0,'张三'),(1,'李四'),(2,'老王'),])                )                # 自定义方法 clean_字段名                # 必须返回值self.cleaned_data['username']                # 如果出错:raise ValidationError('用户名已存在')                def clean_username(self):                    v = self.cleaned_data['username']                    if models.UserInfo.objects.filter(username=v).count():                        # 整体错了                        # 自己详细错误信息                        raise ValidationError('用户名已存在')                    return v                def clean_user_id(self):                    return self.cleaned_data['user_id']                def clean(self):                    value_dict = self.cleaned_data                    v1 = value_dict.get('username')                    v2 = value_dict.get('user_id')                    if v1 == 'root' and v2==1:                        raise ValidationError('整体错误信息')                    return self.cleaned_data

  

 

转载于:https://www.cnblogs.com/keme/p/6561933.html

你可能感兴趣的文章
lnmp高人笔记
查看>>
[转载] OpenCV2.4.3 CheatSheet学习(三)
查看>>
子程序框架
查看>>
多维数组元素的地址
查看>>
数据库运维体系_SZMSD
查看>>
福大软工1816 · 第三次作业 - 结对项目1
查看>>
selenium多个窗口切换
查看>>
《单页面应用》所获知识点
查看>>
静态库 调试版本 和发布版本
查看>>
读书笔记四
查看>>
JAVA中的finalize()方法
查看>>
慕课网学习手记--炫丽的倒计时效果Canvas绘图与动画基础
查看>>
==与equals()的区别
查看>>
基本分类方法——KNN(K近邻)算法
查看>>
在XenCenter6.2中构建CentOS7虚拟机的启动错误
查看>>
.NET Framework3.0/3.5/4.0/4.5新增功能摘要
查看>>
php中表单提交复选框与下拉列表项
查看>>
熟悉常用的Linux操作
查看>>
面象过程与面象对象
查看>>
谷歌设置支持webgl
查看>>