Django 的 form类
来源:互联网 发布:plsql执行sql文件 编辑:程序博客网 时间:2024/05/21 09:37
Django 在表单中的角色
处理表单是一件很复杂的事情。考虑一下Django 的Admin 站点,不同类型的大量数据项需要在一个表单中准备好、渲染成HTML、使用一个方便的界面编辑、返回给服务器、验证并清除,然后保存或者向后继续处理。
Django 的表单功能可以简化并自动化大部分这些工作,而且还可以比大部分程序员自己所编写的代码更安全。
Django 会处理表单工作中的三个显著不同的部分:
准备数据、重构数据,以便下一步提交。
为数据创建HTML 表单
接收并处理客户端提交的表单和数据
可以手工编写代码来实现,但是Django 可以帮你完成所有这些工作。
在Django 中构建一个表单
Form 类
我们已经计划好了我们的 HTML 表单应该呈现的样子。在Django 中,我们的起始点是这里:
forms.pyfrom django import formsclass NameForm(forms.Form): your_name = forms.CharField(label='Your name', max_length=100)
它定义一个Form 类,只带有一个字段(your_name)。我们已经对这个字段使用一个友好的标签,当渲染时它将出现在
字段允许的最大长度通过max_length 定义。它完成两件事情。首先,它在HTML 的 上放置一个maxlength=”100” (这样浏览器将在第一时间阻止用户输入多于这个数目的字符)。它还意味着当Django 收到浏览器发送过来的表单时,它将验证数据的长度。
Form 的实例具有一个is_valid() 方法,它为所有的字段运行验证的程序。当调用这个方法时,如果所有的字段都包含合法的数据,它将:
返回True
将表单的数据放到cleaned_data 属性中。
完整的表单,第一次渲染时,看上去将像:
<label for="your_name">Your name: </label><input id="your_name" type="text" name="your_name" maxlength="100">
注意它不包含 标签和提交按钮。我们必须自己在模板中提供它们。
视图
发送给Django 网站的表单数据通过一个视图处理,一般和发布这个表单的是同一个视图。这允许我们重用一些相同的逻辑。
要操作一个通过URL发布的表单,我们要在视图中实例表单。
views.py
from django.shortcuts import renderfrom django.http import HttpResponseRedirectfrom .forms import NameFormdef get_name(request): # if this is a POST request we need to process the form data if request.method == 'POST': # create a form instance and populate it with data from the request: form = NameForm(request.POST) # check whether it's valid: if form.is_valid(): # process the data in form.cleaned_data as required # ... # redirect to a new URL: return HttpResponseRedirect('/thanks/') # if a GET (or any other method) we'll create a blank form else: form = NameForm() return render(request, 'name.html', {'form': form})
如果访问视图的是一个GET 请求,它将创建一个空的表单实例并将它放置到要渲染的模板的上下文中。这是我们在第一次访问该URL 时预期发生的情况。
如果表单的提交使用POST 请求,那么视图将再次创建一个表单实例并使用请求中的数据填充它:form = NameForm(request.POST)。这叫做”绑定数据至表单“(它现在是一个绑定的表单)。
我们调用表单的is_valid() 方法;如果它不为True,我们将带着这个表单返回到模板。这时表单不再为空(未绑定),所以HTML 表单将用之前提交的数据填充,然后可以根据要求编辑并改正它。
如果is_valid() 为True,我们将能够在cleaned_data 属性中找到所有合法的表单数据。在发送HTTP 重定向给浏览器告诉它下一步的去向之前,我们可以用这个数据来更新数据库或者做其它处理。
模板
我们不需要在name.html 模板中做很多工作。最简单的例子是:
<form action="/your-name/" method="post"> {% csrf_token %} {{ form }} <input type="submit" value="Submit" /></form>
根据{{ form }},所有的表单字段和它们的属性将通过Django 的模板语言拆分成HTML 标记 。
表单和跨站请求伪造的防护
Django 原生支持一个简单易用的跨站请求伪造的防护。当提交一个启用CSRF 防护的POST 表单时,你必须使用上面例子中的csrf_token 模板标签。然而,因为CSRF 防护在模板中不是与表单直接捆绑在一起的,这个标签在这篇文档的以下示例中将省略。
HTML5 输入类型和浏览器验证
如果你的表单包含URLField、EmailField 或其它整数字段类型,Django 将使用url、email和 number 这样的HTML5 输入类型。默认情况下,浏览器可能会对这些字段进行它们自身的验证,这些验证可能比Django 的验证更严格。如果你想禁用这个行为,请设置form 标签的novalidate 属性,或者指定一个不同的字段,如TextInput。
现在我们有了一个可以工作的网页表单,它通过Django Form 描述、通过视图处理并渲染成一个HTML 。
这是你入门所需要知道的所有内容,但是表单框架为了便利提供了更多的内容。一旦你理解了上面描述的基本处理过程,你应该可以理解表单系统的其它功能并准备好学习更多的底层机制。
拓展应用
required:是否可以为空。required=True 不可以为空,required=False 可以为空
max_length=4 最多4个值,超过不会显示
min_length=2 至少两个值,少于两个会返回提示信息
error_messages={‘required’: ‘邮箱不能为空’, ‘invalid’: ‘邮箱格式错误’} 自定义错误信息,invalid 是格式错误
widget=forms.TextInput(attrs={‘class’: ‘c1’}) 给自动生成的input标签自定义class属性
widget=forms.Textarea() 生成Textarea标签。widget默认生成input标签
实战
models.py
from django.db import modelsclass Author(models.Model): """ 作者 """ name = models.CharField(max_length=100) age = models.IntegerField()class BookType(models.Model): """ 图书类型 """ caption = models.CharField(max_length=64)class Book(models.Model): """ 图书 """ name = models.CharField(max_length=64) pages = models.IntegerField() price = models.DecimalField(max_digits=10,decimal_places=2) pubdate = models.DateField() authors = models.ManyToManyField(Author) book_type = models.ForeignKey(BookType)
forms.py:
from django import formsfrom app01 import modelsclass Form1(forms.Form): user = forms.CharField(label='Your name', widget=forms.TextInput(attrs={'class': 'c1'}), error_messages={'required': '用户名不能为空'}, ) pwd = forms.CharField(max_length=4, min_length=2, required=True, error_messages = {'required': '密码不能为空'} ) email = forms.EmailField(error_messages={'required': '邮箱不能为空', 'invalid': '邮箱格式错误'}) memo = forms.CharField( widget=forms.Textarea(),error_messages={'required': 'memo不能为空'} ) vip_type = ( (0, u'普通用户'), (1, u'高级用户'),) vip = forms.CharField(widget=forms.widgets.Select(choices=vip_type, attrs={'class': 'form-control'})) #写上以下代码就不用担心数据库添加了数据而不能及时获取了 def __init__(self, *args, **kwargs): #每次创建Form1对象时执行init方法 super(Form1, self).__init__(*args, **kwargs) self.fields['book_type'] = forms.CharField( widget=forms.widgets.Select(choices=models.BookType.objects.values_list('id', 'caption'), attrs={'class': "form-control"}))
HTML:<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title> <style> .input-group{ position: relative; padding: 20px; width: 250px; } .input-group input{ width: 200px; display: inline-block; } .inline-group span{ display: inline-block; position: absolute; height: 12px; font-size: 8px; border: 1px solid red; background-color: coral; color: white; top: 41px; left: 20px; width: 202px; } </style></head><body> <form action="/form1/" method="POST"> {% csrf_token %}<div class="input-group"><label>用户名:</label>{{ form.user }}<span>{{ form.user.errors }}</span></div><div class="input-group"><label>密码:</label>{{ form.pwd }}<span>{{ form.pwd.errors }}</span></div><div class="input-group"><label>邮箱:</label>{{ form.email }}<span>{{ form.email.errors }}</span></div><div class="input-group"><label>memo:</label>{{ form.memo }}<span>{{ form.memo.errors }}</span></div><div class="input-group"><label>会员等级:</label>{{ form.vip }}<span>{{ form.vip.errors }}</span></div><div> <input type="submit" value="提交" /></div> </form></body></html>
views.py
from django.shortcuts import render,HttpResponsefrom app01.forms import Form1from app01.models import *def form1(request): if request.method == "POST": f = Form1(request.POST) if f.is_valid(): print(f.cleaned_data) else: return render(request,"account/form1.html",{"error":f.errors,"form":f}) else: # 如果不是post提交数据,就不传参数创建对象,并将对象返回给前台,直接生成input标签,内容为空 f = Form1() return render(request,"account/form1.html",{"form":f}) return render(request,"account/form1.html")
Django里面没有手机验证,没有的需要自定义
#!/usr/bin/env python# -*- coding:utf-8 -*-import refrom django import formsfrom django.core.exceptions import ValidationErrordef mobile_validate(value): mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$') if not mobile_re.match(value): raise ValidationError('手机号码格式错误')class PublishForm(forms.Form): user_type_choice = ( (0, u'普通用户'), (1, u'高级用户'), ) user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice, attrs={'class': "form-control"})) title = forms.CharField(max_length=20, min_length=5, error_messages={'required': u'标题不能为空', 'min_length': u'标题最少为5个字符', 'max_length': u'标题最多为20个字符'}, widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': u'标题5-20个字符'})) memo = forms.CharField(required=False, max_length=256, widget=forms.widgets.Textarea(attrs={'class': "form-control no-radius", 'placeholder': u'详细描述', 'rows': 3})) phone = forms.CharField(validators=[mobile_validate, ], error_messages={'required': u'手机不能为空'}, widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': u'手机号码'})) email = forms.EmailField(required=False, error_messages={'required': u'邮箱不能为空','invalid': u'邮箱格式错误'}, widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': u'邮箱'})) def publish(request): ret = {'status': False, 'data': '', 'error': '', 'summary': ''} if request.method == 'POST': request_form = PublishForm(request.POST) if request_form.is_valid(): request_dict = request_form.clean() print request_dict ret['status'] = True else: error_msg = request_form.errors.as_json() ret['error'] = json.loads(error_msg) return HttpResponse(json.dumps(ret))
- Django 的 form类
- Django的form表单
- Django 中form的用法
- Django 中form的用法
- django中form的使用
- Django中form类排版
- Django - Form类 基础篇
- django:通用视图-UpdateView更新有参数的form类
- Django Form
- django form
- django form
- Django---form
- python-django的form的使用
- Django中Form的Textarea字段
- django中form的自定义校验
- django 接收页面form的post数组
- django中form的CSS样式
- Django中 form表单的使用
- java开发系统内核:键盘和窗口关闭API
- linux lsmod命令详解
- 决策树分类器
- 策略模式
- 你知道it都有哪些作用吗?
- Django 的 form类
- 深度学习将成为中国监控市场增长的新引擎
- git
- 成为真正的Python开发者
- u3d基于slua提升开发效率
- 计算机间通信
- 解决Oracle创建视图(VIEW)权限不足的方法
- 数据结构与算法:学习笔记(1)顺序式堆栈(原理与实现)
- Mask R-CNN