疯狂的暑假学习之  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学习笔记(五)—— 表单的更多相关文章

  1. Django学习笔记之表单验证

    表单概述 HTML中的表单 单纯从前端的html来说,表单是用来提交数据给服务器的,不管后台的服务器用的是Django还是PHP语言还是其他语言.只要把input标签放在form标签中,然后再添加一个 ...

  2. Bootstrap学习笔记(二) 表单

    在Bootstrap学习笔记(一) 排版的基础上继续学习Bootstrap的表单,编辑器及head内代码不变. 3-1 基础表单 单中常见的元素主要包括:文本输入框.下拉选择框.单选按钮.复选按钮.文 ...

  3. Vue学习计划基础笔记(五) - 表单输入绑定、组件基础

    表单输入绑定.组件基础 目标: 熟练掌握vue中表单的处理方式 对之前学习的内容简单回顾一下,并写一个实例,学以致用(最好脱离文档) vue中表单的处理方式 vue中表单的处理使用了v-model指令 ...

  4. AngularJS 1.2.x 学习笔记(表单校验篇)

    https://my.oschina.net/cokolin/blog/526911 摘要: 本文首发于 blog.csdn.net/vipshop_ebs/article/details/39472 ...

  5. vue学习笔记(六)表单输入绑定

    前言 在上一章vue学习笔记(四)事件处理器这一篇博客的内容中,我们已经了解vue是如何绑定事件的,而本篇博客主要讲解的是vue中表单输入的绑定,通常我们自己提交信息的时候都是通过表单将信息到服务器的 ...

  6. Symfony2学习笔记之表单

    对于一个Web开发者来说,处理HTML表单是一个最为普通又具挑战的任务.Symfony2集成了一个Form组件,让处理表单变的容易起来.在这一节里,我们将从基础开始创建一个复杂的表单,学习表单类库中最 ...

  7. [知了堂学习笔记]_Jquery_Validate 表单校验的使用

    一.效果图: 二.JqueryValidate的好处 在做注册.或者类似以上的表单提交的时候,大家是不是都很烦那种,把数据拿到后台去判断, 可能经过了正则表达式之类的复杂判断,然后发现数据错误.接着通 ...

  8. [学习笔记]--Jfinal 表单提交附件

    近期.项目里面用到了Jfinal 里面的上传附件. Jfinal 的Controller 里面提供了一个 getFile系列方法提供文件上传. 我这里呢,是文件上传和表单參数一起提交. 页面类似下图: ...

  9. 20151223jquery学习笔记--Ajax表单提交

    传统的表单提交, 需要多次跳转页面, 极大的消耗资源也缺乏良好的用户体验. 而这款form.js 表单的 Ajax 提交插件将解决这个问题.一. 核心方法官方网站: http://malsup.com ...

  10. angular2 学习笔记 ( Form 表单 )

    refer : https://angular.cn/docs/ts/latest/guide/forms.html https://angular.cn/docs/ts/latest/cookboo ...

随机推荐

  1. 一个tomcat部署俩个java web项目

    2.发布的时候可以发布成war包,用项目名称右键export,选择项目名称,还有发布的路径,即tomcat下的路径,参考http://zhidao.baidu.com/link?url=imOu0Uu ...

  2. 关于线程池ThreadPool的学习

    学习重点ThreadPool.SetMinThreads(out workerThreads, out completionPortThreads).这是整个线程池的关键.  而ThreadPool. ...

  3. 开始编写正式的iOS 程序(iOS编程指导)

    App设计基础 在确定了你的App主要功能后,需要把它转化为代码.如果你是第一次开发属于自己的iOS App,需要花些时间熟悉基本概念.iOS内置了很多设计样式,多了解下能对你以后有帮助. 初稿 设计 ...

  4. 安装 vsftp

    1.yum安装 vsftp yum list vsftpd yum install vsftpd 2.配置 vsftp 将root注释掉 vi /etc/vsftpd/ftpusers 将root注释 ...

  5. Android学习----AndroidManifest.xml文件解析

    一个Android应用程序的结构: 一.关于AndroidManifest.xml AndroidManifest.xml 是每个android程序中必须的文件.它位于整个项目的根目录,描述了pack ...

  6. 在sublimetext上打造一个兼容virtualenv的web&python开发环境

    利用Sublimetext3&virtualenv 打造一个Web&Python IDE 注: 环境:window|python3;以下使用的sublimetext插件均用packag ...

  7. 栈的讲解 和 栈的生长方向 源代码技巧分析,简直没SEI 啦

    函数的局部变量,都是存放在"栈"里面,栈的英文是:STACK.STACK的大小,我们可以在stm32的启动文件里面设置,以战舰stm32开发板为例,在startup_stm32f1 ...

  8. decimal类型数据如何保留两位小数

    日常开发中,decimal作为货币类型,经常会处理保留两位小数的问题. 本站整理两种,decimal类型保留两位小数的方法. 第一种: decimal d = 46.28111m;string res ...

  9. c# 重新认识 Double 浮点型

    double test1 = 0; for (int i = 0; i < 100000000; i++) { test1 += 0.0001; } 请问 test1 的值是几? 答案是:999 ...

  10. Java 的性能优化

    jvm 中的方法区: 永久区---存的类的信息.方法.常量 .静态变量 1.Java的性能优化 1.减少gc的压力,优先级比较低的线程,他是一个守护线程 回收我们的堆内存. 2.尽量的避免我们的new ...