热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

10.Djangoform表单

Django中的form表单我们在某个网站注册账号的时候,总会遇到下面的情况:限定用户名的长度最少8位用户输入的密码最短8位,最长28位还有用户输入的手机号或者邮箱验证等

10.Django-form表单

Django中的form表单

我们在某个网站注册账号的时候,总会遇到下面的情况:

限定用户名的长度最少8位
用户输入的密码最短8位,最长28位
还有用户输入的手机号或者邮箱验证等

这些情况都可以由Django的form来实现。

一、Django中的form表单的定义

Django的表单系统中,所有的表单都继承自django.forms.Form

基于Django的表单系统,主要分两类:

  • 基于django.forms.Form:所有表单类的父类
  • 基于django.forms.ModelForm:与模型类绑定的Form

二、Django的form的使用

先在views.py中自定义一个MyForm类

class MyForm(forms.Form):
    user=forms.CharField()
    age=forms.IntegerField()
    email=forms.EmailField()

然后再定义一个reg的视图函数

def reg(request):
    form_obj=MyForm()       # 实例化一个MyForm类
    
    return render(request,"reg.html",{"form_obj":form_obj})

再生成一个reg的网页,配置好路由表,reg.html的内容如下:




    
    


    

{{ error_message }}

{% csrf_token %} {{ form_obj.as_p }}

启动程序,用浏览器打开http://127.0.0.1:8000/reg/后,可以看到浏览器上的页面如下:

在MyForm类中定义了用户名user,年龄age和邮箱email三个注册项,而在前端页面上就显示了三个标签。

所以可以知道这三个标签是由form_obj这个对象创建出来的。

在前端页面提示用户输入信息时都是英文格式,想变成汉语格式的应该怎么办呢???

把上面定义的MyForm类修改

class MyForm(forms.Form):
    user=forms.CharField(label="用户")
    age=forms.IntegerField(label="年龄")
    email=forms.EmailField(label="邮箱")

刷新网页,显示页面如下

查看网页的源码,每个标签由一个label标签和input标签组成,而且每个标签都被一个p标签包围,

在前端页面上只写了form_obj.as_p,所以所有标签都是由Django的模板语言按照form表单的语法渲染出来的。

这种方式生成的代码封装性很好,但是可拓展性太差了。

如果我想在p标签里面再添加一些别的装饰呢,这又怎么办呢???

修改前端页面的代码




    
    


    

{{ error_message }}

{% csrf_token %}

姓名:{{ form_obj.user }}

年龄:{{ form_obj.age }}

邮箱:{{ form_obj.email }}

在这里,我们就生成一个姓名,年龄和邮箱的文本,其余的交由form来渲染,渲染结果如下:

再来看网页的源码

原来的label标签已经没有了,取而代之的是自定义的文本,而且只剩下一个input标签了。

而且可以看到每个标签的type属性不一样,跟MyForm类里定义的字段类型是一样的。

在MyForm类中定义的用户名user字段的类型是CharField类型,渲染后变成了text类型
在MyForm类中定义的用户名age字段的类型是IntegerField类型,渲染后变成了number类型
在MyForm类中定义的用户名email字的类型是EmailField类型,渲染后变成了email类型

而且其name属性和id属性的值都跟MyForm类中定义的字段是一样的。

看完了源码,现在什么信息都不输入就点击提交按钮会发生什么呢??

浏览器提示信息告诉我们用户信息这一栏不能为空。

在用户信息栏里输入信息,再次点击提交按钮,又会在年龄栏中提示不能为空。

在这里如果我们向年龄信息栏中输入的是字母或特殊符号,也会输入不上,而只能输入数字。

因为在MyForm类中定义字段时使用了Integer类型。

同样的,在邮箱字段里也有同样的输入要求。

对用户输入的用户名和密码的长度进行设定

修改MyForm

class MyForm(forms.Form):
    user = forms.CharField(label="用户",min_length=5,max_length=12)
    age = forms.IntegerField(label="年龄")
    email = forms.EmailField(label="邮箱")

刷新浏览器,看会发生什么情况??

提示必须输入的信息的长度不能小于5。

修改reg视图函数

def reg(request):
    if request.method=="POST":
        form_post=MyForm(request.POST)

        print(form_post.is_valid())
    form_obj=MyForm()

    return render(request,"reg.html",{"form_obj":form_obj})

打开IE浏览器,填写如下信息,然后提交

在服务端后台打印的信息如下

False

可以看到is.valid()方法返回的是一个布尔值。

按照正确的要求填写并提交信息后,后台才会打印True

可以知道,Django的form到底有多少层校验取决于views.py的类中每个字段的类型及参数的个数.

如果用户输入的信息符合设定的要求,那么接下来就必须把用户填写的注册信息添加到数据库中。

先修改视图函数,看Django的form把用户输入的数据转换成什么样子的了。

def reg(request):
    if request.method=="POST":
        form_post=MyForm(request.POST)
    
    if form_post.is_valid():
        print("data:",form_post.cleaned_data)
    
    form_obj=MyForm()
    
    return render(request,"reg.html",{"form_obj":form_obj})

刷新浏览器,重新输入注册信息,打印如下

data: {"user": "aaaaaa", "age": 100, "email": "bbbb@qq.com"}

可以看到Django的form把用户输入的信息封装成一个字典了。

此时添加数据库就可以使用关键字参数了。

def reg(request):
    if request.method=="POST":
        form_post=MyForm(request.POST)
    
    if form_post.is_valid():
        print("data:",form_post.cleaned_data)
    
        models.UserInfo.objects.create_user(**form_post)
    
    form_obj=MyForm()
    
    return render(request,"reg.html",{"form_obj":form_obj})

进行校验的时候,如果出现错误,就应该把错误信息返回,该怎么做呢??

先打印下错误信息及错误信息的类型

def reg(request):
    if request.method=="POST":
        form_post=MyForm(request.POST)
    
        if form_post.is_valid():
            print("data:",form_post.cleaned_data)
    
            models.UserInfo.objects.create_ue(**form_post)
        else:
            print(form_post.errors)
                
            print(type(form_post.errors))
    form_obj=MyForm()
    
    return render(request,"reg.html",{"form_obj":form_obj})

打印信息如下:

  • user
    • This field is required.
  • age
    • This field is required.
  • email
    • This field is required.

可以看到,返回的错误信息是一个字典。

既然是一个字典类型,那么就可以取出其中的值。

def reg(request):
    if request.method=="POST":
        form_post=MyForm(request.POST)
    
        if form_post.is_valid():
            print("data:",form_post.cleaned_data)
    
            models.UserInfo.objects.create_ue(**form_post)
        else:
            print("user_errors:",form_post.errors["user"])
            print("age_errors:",form_post.errors["age"])
            print("email_errors:",form_post.errors["email"])
                
    form_obj=MyForm()
    
    return render(request,"reg.html",{"form_obj":form_obj})

打印结果如下:

user_errors: 
  • This field is required.
age_errors:
  • This field is required.
email_errors:
  • This field is required.

返回的信息是一个

  • 标签,其错误信息的内容为"This field is required."

    修改views.py文件

    def reg(request):
        if request.method=="POST":
            form_post=MyForm(request.POST)
        
            if form_post.is_valid():
                print("data:",form_post.cleaned_data)
        
                models.UserInfo.objects.create_user(**form_post)
    	else:
                errors_obj=form_post.errors
                print("user_errors:",errors_obj["user"])
                print("age_errors:",errors_obj["age"])
                print("email_errors:",errors_obj["email"])
        
        form_obj=MyForm()
        
        return render(request,"reg.html",{"form_obj":form_obj,"errors_obj":errors_obj})
    

    修改前端网页reg.html

    
    
    
        
        
    
    
        

    {{ error_message }}

    {% csrf_token %}

    姓名:{{ form_obj.user }}{{ errors_obj.user.0 }}

    年龄:{{ form_obj.age }}{{ errors_obj.age.0 }}

    邮箱:{{ form_obj.email }}{{ errors_obj.email.0 }}

    这样就可以把错误信息渲染到前端网页了,如下所示,正常打开网页时,不会显示错误信息

    当输入的信息不符合定义的要求时,就显在网页上显示错误信息了

    如果想自定义在前端网页上显示的错误信息,该怎么办呢?

    修改MyForm类,如下

    class MyForm(forms.Form):
        user = forms.CharField(label="用户",min_length=5,max_length=12,error_messages={"required":"用户名必填"})
        age = forms.IntegerField(label="年龄",error_messages={"required":"年龄必填"})
        email = forms.EmailField(label="邮箱",error_messages={"required":"邮箱必填"})
    

    此时,再次刷新浏览器,点击提交按钮,显示如下


推荐阅读
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • PDO MySQL
    PDOMySQL如果文章有成千上万篇,该怎样保存?数据保存有多种方式,比如单机文件、单机数据库(SQLite)、网络数据库(MySQL、MariaDB)等等。根据项目来选择,做We ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • 本文介绍了使用Python编写购物程序的实现步骤和代码示例。程序启动后,用户需要输入工资,并打印商品列表。用户可以根据商品编号选择购买商品,程序会检测余额是否充足,如果充足则直接扣款,否则提醒用户。用户可以随时退出程序,在退出时打印已购买商品的数量和余额。附带了完整的代码示例。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • HDFS2.x新特性
    一、集群间数据拷贝scp实现两个远程主机之间的文件复制scp-rhello.txtroothadoop103:useratguiguhello.txt推pushscp-rr ... [详细]
  • 本文主要复习了数据库的一些知识点,包括环境变量设置、表之间的引用关系等。同时介绍了一些常用的数据库命令及其使用方法,如创建数据库、查看已存在的数据库、切换数据库、创建表等操作。通过本文的学习,可以加深对数据库的理解和应用能力。 ... [详细]
  • 从Oracle安全移植到国产达梦数据库的DBA实践与攻略
    随着我国对信息安全和自主可控技术的重视,国产数据库在党政机关、军队和大型央企等行业中得到了快速应用。本文介绍了如何降低从Oracle到国产达梦数据库的技术门槛,保障用户现有业务系统投资。具体包括分析待移植系统、确定移植对象、数据迁移、PL/SQL移植、校验移植结果以及应用系统的测试和优化等步骤。同时提供了移植攻略,包括待移植系统分析和准备移植环境的方法。通过本文的实践与攻略,DBA可以更好地完成Oracle安全移植到国产达梦数据库的工作。 ... [详细]
author-avatar
一粒星尘ch
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有