Django 对用户通过表单提交的数据进行访问,有效性检查,以及其他处理.
1.从requset对象中获得数据
每个view函数的第一个参数是HttpResquest对象
def hello(request): return HttpResponse("Hello world")
如上, 变量request 就是一个HttpRequest 对象, 会它有自己的属性方法,在view 函数执行过程中,可以用这些属性来获取当前request的一些信息,比如加载这个页面的是是谁,或者用的是什么浏览器
URL相关信息
属性/方法 说明 举例
request.path 除域名以外的请求路径,以正斜杠开头 "/hello/"
request.get_host() 主机名(比如,通常所说的域名) "127.0.0.1:8000" or " www.example.com"
request.get_full_path() 请求路径,可能包含查询字符串 "/hello/?print=true"
request.is_secure() 如果通过HTTPS访问,则此方法返回True, 否则返回False True 或者 False
2.有关request的其它信息
request.META 是一个Python字典,包含了所有本次HTTP请求的Header信息,比如用户IP地址和用户Agent
(通常是浏览器的名称和版本号)。 注意,Header信息的完整列表取决于用户所发送的Header信息和服务器
端设置的Header信息。 这个字典中几个常见的键值有:
- HTTP_REFERER ,进站前链接网页,如果有的话。 (请注意,它是 REFERRER 的笔误。)
-
HTTP_USER_AGENT ,用户浏览器的user-agent字符串,如果有的话。 例如:
"Mozilla/5.0 (X11; U; Linux i686; fr‐FR; rv:1.8.1.17) Gecko/20080829 Firefox/2.0.0.17" . -
REMOTE_ADDR 客户端IP,如: "12.345.67.89" 。(如果申请是经过代理服务器的话,那么它可能是以逗号分
割的多个IP地址,如: "12.345.67.89,23.456.78.90" 。)
注意,因为 request.META 是一个普通的Python字典,因此当你试图访问一个不存在的键时,会触发一个
KeyError异常。 (HTTP header信息是由用户的浏览器所提交的、不应该给予信任的“额外”数据,因此你总
是应该好好设计你的应用以便当一个特定的Header数据不存在时,给出一个优雅的回应。)你应该用
try/except 语句,或者用Python字典的 get() 方法来处理这些“可能不存在的键”:
def ua_display_good1(request): try: ua=request.META["HTTP_USER_AGENT"] except KeyError: ua='unknow' return HttpResponse("Your browser is %s" %ua) def ua_display_good2(request): ua=request.META.get('HTTP_USER_AGENT','unknown') return HttpResponse("Your browser is %s" %ua)
可以写一个函数来显示request.MEAT的所有数据,这样你就知道里面有什么了,
def display_meta(request): values = request.META.items() values.sort() html=[] for k,v,in values: html.append(''%(k,v)+"\n") return HttpResponse(' %s %s %s '%'\n'.join((html)))
3.提交的数据信息
除了基本的元数据,HttpRequest对象还有两个属性包含了用户所提交的信息: request.GET 和 request.POST 二者都是类字典对象,你可以通过它们来访问GET和POST数据.
类字典对象: requeset.GET request.POST是类字典对象,他们的行为像Python里标准字典对象,但是在技术底层不是标准字典, 虽然他们都有get(),keys() 和 values()方法,你可以用for key in request.GET 获取所有的键,但是他们还有一些普通字典没有的方法.
Post数据是来自html的
表单开发分为两部分,前端html页面用户接口和后台view函数对所提交的数据的处理过程
----一个表单处理示例
首先在view建立一个显示一个搜索表单:
def search_form(request): return render_to_response('search_form.html')
serch_form.html
DOCTYPE html>
<html>
<head>
<title>Searchheeltitle>
head>
<body>
<form action="/search/" method="get">
<input type="text" name="q">
<input type="submit" value="Search">
form>
body>
html>
然后在url匹配,还有一点,就是在引用这个Temlate的时候,总是会显示TemplateDoesNotExist错误.原因是没有把html文件的目录放在settings 中,
可以在settings中添加
TEMPLATE_DIRS = (os.path.join(BASE_DIR, 'templates').replace('\\','/'),)
然后模板的目录就是,把html文件放在template文件中即可
.然后写action中 "/search/" 的views实现:
def search(request): if 'q' in request.GET: message="You searched: %r " % request.GET['q'] else: message='You submitted an empty form' return HttpResponse(message)
那数据是如何在这个系统中传递的呢?
- 首先我们在html中定义了一个q,当提交表单的时候,变量q的值通过GET(metho="get") 附加在URL/search/上
- 处理/search/的视图,通过request.GET 来获取q的值
- 需要注意的是这里需要判断q是否在GET中,对于用户提交过来的数据要进行过滤,和检查,否则会有异常,如这可能会有keyError
- 我还想知道GET传递了什么内容
5,HttpResponseRedirect对象将网页重定向至一个包含成功信息的页面, 若一个用户刷新一个包含post表单的页面,那么请求将会重新发生找成重复, 如果在post表单之后重定向到另外的网页就不会造成重复请求, 所以不是直接 reder_to_response() ,我们应该为每次成功的post请求做重定向
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','[email protected]'), ['[email protected]'], ) return HttpResponseRedirect('/contact/thanks') return render_to_response('contact_form.html',{'errors':errors})
6.高级库的用意--- 处理表单和相关校验任务
- 第一个Form类: 处理html 表单显示以及验证( Django的 newform)
- 表单框架主要用法,为每个要处理的html的"
__author__ = 'peggy' from django import forms class ContactForm(forms.Form): subject = forms.CharField() email=forms.EmailField(required=False) message = forms.CharField()
表单中每个字段(域)作为form类的属性,被展现为Field类,表单在python解释器里面,把自己显示成为html
Form 对象做的第二件事是校验数据。 为了校验数据,我们创建一个新的对 Form 象,并且传入一个与定义匹配的
-
字典类型数据:
>>> f = ContactForm({'subject': 'Hello', 'email': '[email protected]', 'message': 'Nice site!'})
一旦你对一个 Form 实体赋值,你就得到了一个绑定form:
>>> f.is_bound
True
调用任何绑定form的 is_valid() 方法,就可以知道它的数据是否合法。 我们已经为每个字段传入了值,因此整
个 Form 是合法的:
>>> f.is_valid()
True
如果我们不传入 email 值,它依然是合法的。因为我们指定这个字段的属性 required=False :
>>> f = ContactForm({'subject': 'Hello', 'message': 'Nice site!'})
>>> f.is_valid()
True
但是,如果留空 subject 或 message ,整个 Form 就不再合法了:
>>> f = ContactForm({'subject': 'Hello'})
>>> f.is_valid()
False
>>> f = ContactForm({'subject': 'Hello', 'message': ''})
>>> f.is_valid()
False
你可以逐一查看每个字段的出错消息:
>>> f = ContactForm({'subject': 'Hello', 'message': ''})
>>> f['message'].errors
[u'This field is required.']
>>> f['subject'].errors
[]
>>> f['email'].errors
[]
1
每一个邦定 Form 实体都有一个 errors 属性,它为你提供了一个字段与错误消息相映射的字典表。
>>> f = ContactForm({'subject': 'Hello', 'message': ''})
>>> f.errors
{'message': [u'This field is required.']}
最终,如果一个 Form 实体的数据是合法的,它就会有一个可用的 cleaned_data 属性。 这是一个包含干净的提交
数据的字典。 Django的form框架不但校验数据,它还会把它们转换成相应的Python类型数据,这叫做清理数
据。
>>> f = ContactForm({subject': Hello, email: [email protected], message: Nice site!})
>>> f.is_valid()
True
>>> f.cleaned_data
{message': uNice site!, email: [email protected], subject: uHello}
我们的contact form只涉及字符串类型,它们会被清理成Unicode对象。如果我们使用整数型或日期型,form
框架会确保方法使用合适的Python整数型或 datetime.date 型对象。
表单form框架处理HTML显示,数据校验,数据清理和表单错误重现
- 改变字段显示 : 通过 widget来修改 message=forms.CharField(widget=forms.Textarea)
- 设置最大长度 : subject=forms.CharField(max_length=100)
- 设置初始值: 创建Form实体的时候,使用initial参数:
-
form=ContactForm( initial={'subject':I love your site} )
- 自定义校验规则
- 指定标签
- 定制Form设计