表单
这篇主要说视图函数中的参数request以及表单相关操作。
HttpRequest简介
从Request对象中获取数据
1 def displayMeta(request): 2 print request 3 return HttpResponse("run right")
定义视图函数、修改urls.py,运行服务器查看代码效果。
该函数会在dos命令行窗口打印request的全部信息,而浏览器会显示‘run right'。
我们只是要看看看request(HttpRequest)包含什么东东。
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 |
HttpRequest有一个很重要的字段(META)。request.META 是一个Python字典,包含了所有本次HTTP请求的Header信息。
HTTP_REFERER,进站前链接网页,如果有的话
HTTP_USER_AGENT,用户浏览器的user-agent字符串,如果有的话
REMOTE_ADDR ,客户端IP(如果申请是经过代理服务器的话,那么它可能是以逗号分割的多个IP地址)
注意,因为 request.META 是一个普通的Python字典,因此当你试图访问一个不存在的键时,会触发一个KeyError异常。你应该用 try/except 语句,或者用Python字典的 get() 方法来处理这些“可能不存在的键”。
展示request.META所有的数据。
我新建了一个forms的app单独存放这些内容,顺便复习一下(还记得Python manage.py startapp forms这个命令吧)
建立了app,还要做什么呢?还要在settings.py中INSTALLED_APPS中进行注册哦。
我为forms这个app新建了模板的路径,这也要在settings.py中注册的(TEMPLATE_DIRS)
TEMPLATE_DIRS=( os.path.join(BASE_DIR,'mysite\\templates').replace('\\','/'), os.path.join(BASE_DIR,'forms\\temp').replace('\\','/'), )
在app forms文件夹下的views.py中新建如下视图函数
1 def display_meta(request): 2 values = request.META.items() 3 values.sort() 4 html = [] 5 for k, v in values: 6 html.append('<tr><td>%s</td><td>%s</td></tr>' % (k, v)) 7 return HttpResponse('<table>%s</table>' % '\n'.join(html))
注册URLconf
url(r'^forms/display_meta/$',display_meta),
运行(Python manage.py runserver 9200)
再复习一下Template的内容,新建一个html模板来展示request.META
在forms/temp文件下新建一个displatmeta.html
1 <html> 2 <title></title> 3 <style> 4 table { 5 border-collapse: collapse; 6 border: none; 7 } 8 9 td { 10 border: solid 1px blue; 11 } 12 </style> 13 <body> 14 <table> 15 {% for k,v in META %} 16 <tr> 17 <td>{{k}}</td> 18 <td>{{v}}</td> 19 </tr> 20 {% endfor %} 21 </table> 22 </body> 23 </html>
在views.py中增加视图函数
1 def displayMeta(request): 2 values = request.META.items() 3 c=Context({"META":values}) 4 return render_to_response("displatmeta.html",c)
最后不要忘记配置urls.py
url(r'^forms/displayMeta/$',displayMeta),
访问下
表单内容
通常,表单开发分为两个部分: 前端HTML页面用户接口和后台view函数对所提交数据的处理过程。 第一部分很简单,来建立个view来显示一个搜索表单:
1 def search_form(request): 2 return render_to_response('search_form.html')
这个view函数可以放到Python的搜索路径的任何位置,包括我们新建的forms app。我将它放在forms/views.py里。
新建模板文件forms/temp下
<html> <head> <title>Search</title> </head> <body> <form action="/forms/search/" method="get"> <input type="text" name="q"> <input type="submit" value="Search"> </form> </body> </html>
注册URLconf,运行如下
这个Form指向的URL /search/ 还没有被实现,所以点击提交会出错。
实现/search/
1 def search(request): 2 if 'q' in request.GET: 3 message = 'You searched for: %r' % request.GET['q'] 4 else: 5 message = 'You submitted an empty form.' 6 return HttpResponse(message)
与数据库交互
修改一下我们的展示结果与过滤函数,用来和之前的books app中定义的数据进行交互一下
新增页面forms\temp\search_results.html
1 <p>You searched for : <strong>{{query}}</strong></p> 2 {% if books %} 3 <p> Found {{books|length}} book{{books|pluralize}}</p> 4 <ul> 5 {% for book in books %} 6 <li>{{book.title}}</li> 7 {% endfor %} 8 </ul> 9 {% else %} 10 <p>No books matched your search criteria.</p> 11 {% endif %}
{{books|length}}获取books的长度
{{books|pluralize}}会适时的增加’s',比如检索结果有多本书,下边实例就是如此。
关于过滤器,Django模板-模板标签末尾有讲到
修改视图函数(记得引入models)
1 from mysite.books.models import * 2 3 def search(request): 4 if 'q' in request.GET and request.GET['q']: 5 q = request.GET['q'] 6 books = Book.objects.filter(title__icontains=q) 7 return render_to_response('search_results.html', 8 {'books': books, 'query': q}) 9 else: 10 return HttpResponse('Please submit a search term.')
运行效果如下:
有输入检索词时
无检索词时
改进表单
在检测到空字符串时更好的解决方法是重新显示表单,并在表单上面给出错误提示以便用户立刻重新填写。 最简单的实现方法既是添加else分句重新显示表单,代码如下:
1 def search(request): 2 if 'q' in request.GET and request.GET['q']: 3 q = request.GET['q'] 4 books = Book.objects.filter(title__icontains=q) 5 return render_to_response('search_results.html', 6 {'books': books, 'query': q}) 7 else: 8 ## return HttpResponse('Please submit a search term.') 9 return render_to_response('search_form.html',{'error':True})
同时修改我们的search_form.html,以便接受error参数
1 <html> 2 <head> 3 <title>Search</title> 4 </head> 5 <body> 6 {% if error %} 7 <p style="color:red;">Please submit a search term</p> 8 {% endif %} 9 <form action="/forms/search/" method="get"> 10 <input type="text" name="q"> 11 <input type="submit" value="Search"> 12 </form> 13 </body> 14 </html>
再次运行结果如下
通过上面的一些修改,现在程序变的好多了,但是现在出现一个问题: 是否有必要专门编写search_form()来显示表单?我们继续修改如下
1 def search(request): 2 error = False 3 if 'q' in request.GET : 4 q = request.GET['q'] 5 if not q: 6 error = True 7 else: 8 books = Book.objects.filter(title__icontains=q) 9 return render_to_response('search_results.html', 10 {'books': books, 'query': q}) 11 12 return render_to_response('search_form.html',{'error':error})
我们直接请求/search/,当GET不到参数q时返回模板search_form.html,有参数q时展示检索结果search_results.html
这俩模板都对应同一个action(视图函数),因此search_form.html中可以修改如下
<!--<form action="/forms/search/" method="get">-->
<form action="" method="get">
小结
本篇就写这些吧。下篇将记录一下简单验证的内容。