Django学习笔记(五)—— 表单
疯狂的暑假学习之 Django学习笔记(五)—— 表单
參考:《The Django Book》 第7章
1. HttpRequest对象的信息
request.path 除域名以外的请求路径,斜杠开头 “/hello/”
request.get_host() 主机名 “127.0.0.1:8000” or “www.xxxx.com”
request.get_full_path() 请求路径,可能包括查询字符串 “/hello/?
print=true”
request.is_secure() 是否通过Https訪问 是为True。否为False
request.META 一个字典。包括本次Http请求的Header信息 比如 REMOTE_ADDR 表示clientip,
HTTP_USER_AGENT表示用户浏览器user-agent字符串
HTTP_REFERER表示进站前连接网页
request.POST 一个类字典对象保存html中<form>标签提交的内容
request.GET 一个类字典对象保存html中<form>标签提交的内容或者URL中的查询字符串
样例:显示request.META
中的全部信息在view.py中增加以下代码。并在urls.py加上相应的URLpattern
def test(request):
values = request.META.items()
values.sort()
html = []
for k,v in values:
html.append('<tr><td>%s</td><td>%s</td></tr>' % (k,v))
return HttpResponse('<table>%s</table>' % '\n'.join(html))
2. 一个简单的表单处理
在templates中创建search_form.html模板:
<html>
<head>
<title>Search</title>
</head>
<body>
{% if error %}
<p style="color: red;">Please submit a search term.</p>
{% endif %}
<form action='' method='get'>
<input type='text' name='q'>
<input type='submit' value='Search'>
</form>
</body>
</html>
当中action=''
表示表单将提交给与当前页面同样的URL再加入search_results.html
<p>You searched for: <strong>{{ query }}</strong></p> {% if books %}
<p>Found {{ books|length }} book{{ books|pluralize }}.</p>
<ul>
{% for book in books %}
<li>{{ book.title }}</li>
{% endfor %}
</ul>
{% else %}
<p> No books matched your search criteria. </p>
{% endif %}
在view.py中加入:
def search(request):
error = False
if 'q' in request.GET:
q = request.GET['q']
if not q:
error = True
else:
books = Book.objects.filter(title__icontains=q)
return render_to_response('search_results.html',
{'books':books,'query':q})
return render_to_response('search_form.html',
{'error':error})
当中Book.objects.filter(title__icontains=q) 是用来获取数据库中标题包括q的书籍。icontains是一个查询keyword。
在urls.py 中加入
(r'search/$',search),
然后在浏览器输入
http://127.0.0.1:8000/search/ 能够看到一个简单的搜索界面。
3. 简单的验证
能够用Javascript在client浏览器进行验证。但可能有些人会将Javascript关闭。而且另一些怀有恶意的用户会尝试提交非法的数据来探測是否有能够攻击的机会。所以除了用Javascript在client浏览器进行验证外,还须要在server验证一次。上面的代码,仅仅对
输入为空做了验证。以下加入一个验证搜索keyword是否小于20个字符的验证。样例:
改动view.py
def search(request):
errors = []
if 'q' in request.GET:
q = request.GET['q']
if not q:
errors.append('Enter a search term')
elif len(q) > 20:
errors.append('Please enter at most 20 characters.')
else:
books = Book.objects.filter(title__icontains=q)
return render_to_response('search_results.html',
{'books':books,'query':q})
return render_to_response('search_form.html',
{'errors':errors})
改动 search_form.html :
<html>
<head>
<title>Search</title>
</head>
<body>
{% if errors %}
{% for error in errors%}
<p style="color: red;">{{ error }}</p>
{% endfor %}
{% endif %}
<form action='' method='get'>
<input type='text' name='q'>
<input type='submit' value='Search'>
</form>
</body>
</html>
4. 编写Contact表单
一个较为复杂的样例:这个表单包含用户提交的反馈信息,一个能够选择填不填的e-mail地址。
view.py
中加入:
def contact(request):
errors = []
if request.method == 'POST':
if not request.POST.get('subject', ''):
errors.append('Enter a subject.')
if not request.POST.get('message', ''):
errors.append('Enter a message.')
if request.POST.get('email') and '@' not in request.POST['email']:
errors.append('Enter a valid e-mail address.')
if not errors:
send_mail(
request.POST['subject'],
request.POST['message'],
request.POST.get('email', 'noreply@example.com'),
['siteowner@example.com'],
)
return HttpResponseRedirect('/contact/thanks/')
return render_to_response('contact_form.html', {
'errors': errors,
'subject': request.POST.get('subject', ''),
'message': request.POST.get('message', ''),
'email': request.POST.get('email', ''),
},context_instance=RequestContext(request))
用POST不用GET,由于这个表单会有一个server端的操作:send_mail。
在templates中加入contact_form.html
:
<html>
<head>
<title>Contact us</title>
</head>
<body>
<h1>Contact us</h1> {% if errors %}
<ul>
{% for error in errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %} <form action="/contact/" method="post">
{% csrf_token %}
<p>Subject: <input type="text" name="subject" value="{{ subject }}"></p>
<p>Your e-mail (optional): <input type="text" name="email" value="{{ email }}"></p>
<p>Message: <textarea name="message" rows="10" cols="50">{{ message }}</textarea></p>
<input type="submit" value="Submit">
</form>
</body>
</html>
这个样例看起来杂乱。解决方法看以下用forms。
5. from类
上面的那个样例,看起来杂乱,而且easy出错。
Django带有一个form库,称为django.forms,这个库能够处理HTML表单显示以及验证。
新建
forms.py 增加
from django import forms class ContactForm(forms.Form):
subject = forms.CharField()
email = forms.EmailField(required=False)
message = forms.CharField()
非常像模块中用的语法。默认是每一个字段必填的,假设要是能够不填的要指定required=False,就像上面的email字段一样。
来看看forms类究竟是什么:它做的第一个是就是将自己显示成HTML
>>> from contact.forms import ContactForm
>>> f = ContactForm()
>>> print f
<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" name="subject" type="text" /></td></tr>
<tr><th><label for="id_email">Email:</label></th><td><input id="id_email" name="email" type="email" /></td></tr>
<tr><th><label for="id_message">Message:</label></th><td><input id="id_message" name="message" type="text" /></td></tr>
默认是依照
<table> 现实输出的,还能够:
>>> print f.as_ul()
<li><label for="id_subject">Subject:</label> <input id="id_subject" name="subject" type="text" /></li>
<li><label for="id_email">Email:</label> <input id="id_email" name="email" type="email" /></li>
<li><label for="id_message">Message:</label> <input id="id_message" name="message" type="text" /></li>
>>> print f.as_p()
<p><label for="id_subject">Subject:</label> <input id="id_subject" name="subject" type="text" /></p>
<p><label for="id_email">Email:</label> <input id="id_email" name="email" type="email" /></p>
<p><label for="id_message">Message:</label> <input id="id_message" name="message" type="text" /></p>
还能够这样显示
>>> print f['subject']
<input id="id_subject" name="subject" type="text" />
forms对象做的第二件事是校验数据。如今先加入数据:
>>> f = ContactForm({'subject': 'Hello', 'email': 'adrian@example.com', 'message': 'Nice site!'})
>>>
一旦对一个forms对象实体赋值。就能够得到一个绑定的form:
>>> f.is_bound
True
>>>
还能够验证数据是否合法
>>> f.is_valid()
True
>>>
假设合法为True。假设不合法为False。如:假设subject或者,essage为空。f.is_valid()就会返回False
也能够查看每一个字段的error
>>> f = ContactForm({'subject': 'Hello', 'message': ''})
>>> f['message'].errors
[u'This field is required.']
>>> f['subject'].errors
[]
>>>
还能够通过errors属性查看错误
>>> f.errors
{'message': [u'This field is required.']}
>>>
假设forms合法,他就有一个cleaned_data属性,将数据转化成Python类型数据,存放在cleaned_data中。
比如:假设是字符串就会被清理成Unicode对象,整数会被清理成Python整数,日期清理成datetime.date型对象
>>> f = ContactForm({'subject': 'Hello', 'email': 'adrian@example.com', 'message': 'Nice site!'})
>>> f.is_valid()
True
>>> f.cleaned_data
{'message': u'Nice site!', 'email': u'adrian@example.com', 'subject': u'Hello'}
6. 在视图中使用Form对象
样例:
view.py
from django.shortcuts import render
from contact.forms import ContactForm
from django.http import HttpResponseRedirect
from django.core.mail import send_mail def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
send_mail(
cd['subject'],
cd['message'],
cd.get('email', 'noreply@example.com'),
['siteowner@example.com'],
)
return HttpResponseRedirect('/contact/thanks/')
else:
form = ContactForm()
return render(request, 'contact_form.html', {'form': form})
contact_form.html
<html>
<head>
<title>Contact us</title>
</head>
<body>
<h1>Contact us</h1> {% if form.errors %}
<p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below.
</p>
{% endif %} <form action="" method="post">
<table>
{{ form.as_table }}
</table>
{% csrf_token %}
<input type="submit" value="Submit">
</form>
</body>
</html>
上面的样例有个缺陷,message这个表单变成了 input type=“text”。
我们能够通过设置widget来改动它:
from django import forms class ContactForm(forms.Form):
subject = forms.CharField()
email = forms.EmailField(required=False)
message = forms.CharField(widget=forms.Textarea)
还能够设置最大长度
设置max_length
from django import forms class ContactForm(forms.Form):
subject = forms.CharField(max_length=20)
email = forms.EmailField(required=False)
message = forms.CharField(widget=forms.Textarea)
设置初始值:
在view.py中ContectForm中加入 initial 參数:
from django.shortcuts import render
from contact.forms import ContactForm
from django.http import HttpResponseRedirect
from django.core.mail import send_mail def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
send_mail(
cd['subject'],
cd['message'],
cd.get('email', 'noreply@example.com'),
['siteowner@example.com'],
)
return HttpResponseRedirect('/contact/thanks/')
else:
form = ContactForm(
initial={'subject': 'AAAAAA'}
)
return render(request, 'contact_form.html', {'form': form})
注意:默认值与表单传入是有差别的。差别在于,假设只传入默认值,是没有绑定的。
7. 自己定义校验规则
比如我们须要加入 message 字段有一个额外的校验,我们就要摘forms类中加入 clean_message() 方法
样例:加入校验 messge中的单词数量(注意不是字母数量。看 split() )要不少于4个.
from django import forms class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
email = forms.EmailField(required=False)
message = forms.CharField(widget=forms.Textarea) def clean_message(self):
message = self.cleaned_data['message']
num_words = len(message.split())
if num_words < 4:
raise forms.ValidationError("Not enough words!")
return message
Django学习笔记(五)—— 表单的更多相关文章
- Django学习笔记之表单验证
表单概述 HTML中的表单 单纯从前端的html来说,表单是用来提交数据给服务器的,不管后台的服务器用的是Django还是PHP语言还是其他语言.只要把input标签放在form标签中,然后再添加一个 ...
- Bootstrap学习笔记(二) 表单
在Bootstrap学习笔记(一) 排版的基础上继续学习Bootstrap的表单,编辑器及head内代码不变. 3-1 基础表单 单中常见的元素主要包括:文本输入框.下拉选择框.单选按钮.复选按钮.文 ...
- Vue学习计划基础笔记(五) - 表单输入绑定、组件基础
表单输入绑定.组件基础 目标: 熟练掌握vue中表单的处理方式 对之前学习的内容简单回顾一下,并写一个实例,学以致用(最好脱离文档) vue中表单的处理方式 vue中表单的处理使用了v-model指令 ...
- AngularJS 1.2.x 学习笔记(表单校验篇)
https://my.oschina.net/cokolin/blog/526911 摘要: 本文首发于 blog.csdn.net/vipshop_ebs/article/details/39472 ...
- vue学习笔记(六)表单输入绑定
前言 在上一章vue学习笔记(四)事件处理器这一篇博客的内容中,我们已经了解vue是如何绑定事件的,而本篇博客主要讲解的是vue中表单输入的绑定,通常我们自己提交信息的时候都是通过表单将信息到服务器的 ...
- Symfony2学习笔记之表单
对于一个Web开发者来说,处理HTML表单是一个最为普通又具挑战的任务.Symfony2集成了一个Form组件,让处理表单变的容易起来.在这一节里,我们将从基础开始创建一个复杂的表单,学习表单类库中最 ...
- [知了堂学习笔记]_Jquery_Validate 表单校验的使用
一.效果图: 二.JqueryValidate的好处 在做注册.或者类似以上的表单提交的时候,大家是不是都很烦那种,把数据拿到后台去判断, 可能经过了正则表达式之类的复杂判断,然后发现数据错误.接着通 ...
- [学习笔记]--Jfinal 表单提交附件
近期.项目里面用到了Jfinal 里面的上传附件. Jfinal 的Controller 里面提供了一个 getFile系列方法提供文件上传. 我这里呢,是文件上传和表单參数一起提交. 页面类似下图: ...
- 20151223jquery学习笔记--Ajax表单提交
传统的表单提交, 需要多次跳转页面, 极大的消耗资源也缺乏良好的用户体验. 而这款form.js 表单的 Ajax 提交插件将解决这个问题.一. 核心方法官方网站: http://malsup.com ...
- angular2 学习笔记 ( Form 表单 )
refer : https://angular.cn/docs/ts/latest/guide/forms.html https://angular.cn/docs/ts/latest/cookboo ...
随机推荐
- 新建android系统服务
一.Android系统服务 Android提供了很多系统服务:如ActivityManger,PowerManger,WindowManger,WifiManger等等. 这些服务都是系统启动开始就一 ...
- Swift - 05 - 数值型字面量
//: Playground - noun: a place where people can play import UIKit var str = "Hello, playground& ...
- Css3中的响应式布局的应用
Media Queries直译过来就是“媒体查询”,在我们平时的Web页面中head部分常看到这样的一段代码: <link href="css/reset.css" rel= ...
- Android中两种设置全屏或者无标题的方法
在开发中我们经常需要把我们的应用设置为全屏或者不想要title, 这里是有两种方法的,一种是在代码中设置,另一种方法是在配置文件里改: 一.在代码中设置: package jason.tutor; i ...
- createElement()结合appendChild()的实例
createElement()作用是在JavaScript中创建一个元素 appendChild()向html元素添加节点 下面是冲浪后改编的例子代码 先插html代码 <body> &l ...
- terminal命令
新建一个文件并写入内容: echo hello world > a.txt (每次echo都会重写文件) 新建文件: touch a.txt 新建目录: mkdir work 用vim打开文件 ...
- CSS实现div居中
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- codevs 1198 国王游戏
传送门 题目描述 Description 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n位 ...
- Solr4.8.0源码分析(11)之Lucene的索引文件(4)
Solr4.8.0源码分析(11)之Lucene的索引文件(4) 1. .dvd和.dvm文件 .dvm是存放了DocValue域的元数据,比如DocValue偏移量. .dvd则存放了DocValu ...
- 分析智能卡的ATR格式
一些例子 NXP 080=========3b f8 T0 Y1 = 0xF(TA1, TB1, TC1, TD1), K = 813 TA1 F = 0x1(Fi = 372, Fmax = 5 ...