1.从Request对象中获取数据
每个view函数的第一个参数是一个HttpRequest对象,在view函数的执行过程中,你可以用这些属性来获取当前request的一些信息(比如,你正在加载这个页面的用户是谁,或者用的是什么浏览器)。
HttpRequest对象包含当前请求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(通常是浏览器的名称和版本号)。这个字典中几个常见的键值有:
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" 。)
3.提交数据信息
除了基本的元数据,HttpRequest对象还有两个属性包含了用户所提交的信息: request.GET 和 request.POST。二者都是类字典对象,你可以通过它们来访问GET和POST数据。
获取使用POST方法的数据与GET的相似,只是使用request.POST代替了request.GET。那么,POST与GET之间有什么不同?当我们提交表单仅仅需要获取数据时就可以用GET; 而当我们提交表单时需要更改服务器数据的状态,或者说发送e-mail,或者其他不仅仅是获取并显示数据的时候就使用POST。
4.一个简单的表单处理示例
通常,表单开发分为两个部分: 前端HTML页面用户接口和后台view函数对所提交数据的处理过程。
# urls.py urlpatterns = patterns('', # ... (r'^search-form/$', views.search_form), (r'^search/$', views.search), # ... ) # views.py def search_form(request): return render_to_response('search_form.html') def search(request): if 'q' in request.GET: message = 'You searched for: %r' % request.GET['q'] else: message = 'You submitted an empty form.' return HttpResponse(message) # search_form.html <html> <head> <title>Search</title> </head> <body> <form action="/search/" method="get"> <input type="text" name="q"> <input type="submit" value="Search"> </form> </body> </html>
1).在HTML里我们定义了一个变量q。当提交表单时,变量q的值通过GET(method=”get”)附加在URL /search/上。
2).处理/search/(search())的视图通过request.GET来获取q的值。
5.From类
Django带有一个form库,称为django.forms,这个库可以处理我们本章所提到的包括HTML表单显示以及验证。
表单框架最主要的用法是,为每一个将要处理的HTML的 <Form> 定义一个Form类。在这个例子中,我们只有一个 <Form> ,因此我们只需定义一个Form类。 这个类可以存在于任何地方,甚至直接写在 views.py 文件里也行,但通常惯例是把Form类都放到一个文件中:forms.py。例如:
from django import forms class ContactForm(forms.Form): subject = forms.CharField() email = forms.EmailField(required=False) message = forms.CharField()
form对象执行过程:
它做的第一件事是将自己显示成HTML:
>>> from contact.forms import ContactForm >>> f = ContactForm() >>> print f <tr><th><label for="id_subject">Subject:</label></th><td><input type="text" name="subject" id="id_subject" /></td></tr> <tr><th><label for="id_email">Email:</label></th><td><input type="text" name="email" id="id_email" /></td></tr> <tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>
Form对象做的第二件事是校验数据。为了校验数据,我们创建一个新的对Form象,并且传入一个与定义匹配的字典类型数据。一旦你对一个Form实体赋值,你就得到了一个绑定form:
>>> f = ContactForm({'subject': 'Hello', 'email': 'adrian@example.com', 'message': 'Nice site!'}) >>> f.is_bound True >>> f.is_valid() True
每一个邦定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: adrian@example.com, message: Nice site!}) >>> f.is_valid() True >>> f.cleaned_data {message': uNice site!, email: uadrian@example.com, subject: uHello}
自定义校验规则:
我们希望 message 字段有一个额外的校验,我们增加一个 clean_message() 方法到 Form 类:
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的form系统自动寻找匹配的函数方法,该方法名称以clean_开头,并以字段名称结束。 如果有这样的方法,它将在校验时被调用。
注:clean_message()方法将在指定字段的默认校验逻辑执行之后被调用。(本例中,在必填CharField这个校验逻辑之后。)因为字段数据已经被部分处理,所以它被从self.cleaned_data中提取出来了。同样,我们不必担心数据是否为空,因为它已经被校验过了。