表单

这篇主要说视图函数中的参数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>' % '
'.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 empsearch_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">

小结

本篇就写这些吧。下篇将记录一下简单验证的内容。

原文地址:https://www.cnblogs.com/cotton/p/3858683.html