Python框架之Django学习笔记(十六)

时间:2021-11-04 13:26:38

Django框架之表单(续)

  今天简直无力吐槽了,去了香山,结果和网上看到的简直是天壤之别啊,说好的香山的枫树呢?说好的香山的红叶呢?说好的漫山遍野一片红呢?本以为在山上,一口气爬上去,沿路基本都是翠绿的松柏,松柏啊亲,难道我不仅红绿色盲,还是一个松枫不辨星人!更坑爹的是回来的时候,排队等公交等了近三个小时,你说为什么不自驾游?没办法,穷人开不起撒。总之,一句话总结香山之旅:

  如果你恨他/她,就让他/她周末去香山吧,如果他/她爱你,就让他/她周末带你去香山吧!恩,闲扯到此为止,虽然挺累,不过学习还是要接着进行滴,况且学习本就需要坚持,没点点毅力,三天打鱼,两天晒网,哪能学到什么东西呢。

表单改进

  首先,我们在基于上次的基础上,对表单进行一些小的改进,上次的search()视图对于空字符串的处理相当薄弱——仅显示一条”Please submit a search term.”的提示信息。 若用户要重新填写表单必须自行点击“后退”按钮, 这种做法既糟糕又不专业。如果在现实的案例中,我们这样子编写,那么Django的优势将荡然无存。

  在检测到空字符串时更好的解决方法是重新显示表单,并在表单上面给出错误提示以便用户立刻重新填写。 最简单的实现方法既是添加else分句重新显示表单,代码如下:

 from django.http import HttpResponse
from django.shortcuts import render_to_response
from books.models import Book def search_form(request):
return render_to_response('search_form.html') def search(request):
if 'q' in request.GET and request.GET['q']:
q = request.GET['q']
books = Book.objects.filter(title__icontains=q)
return render_to_response('search_results.html',
{'books': books, 'query': q})
else:
**return render_to_response('search_form.html', {'error': True})**

  PS:将search_form()视图也包含进来以便查看

  这段代码里,我们改进来search()视图:在字符串为空时重新显示search_form.html。 并且给这个模板传递了一个变量error,记录着错误提示信息。 现在我们编辑一下search_form.html,检测变量error:  

 <html>
<head>
<title>Search</title>
</head>
<body>
**{% if error %}**
**<p style="color: red;">Please submit a search term.</p>**
**{% endif %}**
<form action="/search/" method="get">
<input type="text" name="q">
<input type="submit" value="Search">
</form>
</body>
</html>

  我们修改了search_form()视图所使用的模板,因为search_form()视图没有传递error变量,所以在条用search_form视图时不会显示错误信息。

  通过上面的一些修改,现在程序变的好多了,但是现在出现一个问题: 是否有必要专门编写search_form()来显示表单? 按实际情况来说,当一个请求发送至/search/(未包含GET的数据)后将会显示一个空的表单(带有错误信息)。 所以,只要我们改变search()视图:当用户访问/search/并未提交任何数据时就隐藏错误信息,这样就移去search_form()视图以及对应的URLpattern。 

 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})

  在改进后的视图中,若用户访问/search/并且没有带有GET数据,那么他将看到一个没有错误信息的表单; 如果用户提交了一个空表单,那么它将看到错误提示信息,还有表单; 最后,若用户提交了一个非空的值,那么他将看到搜索结果。

  最后,我们再稍微改进一下这个表单,去掉冗余的部分。 既然已经将两个视图与URLs合并起来,/search/视图管理着表单的显示以及结果的显示,那么在search_form.html里表单的action值就没有必要硬编码的指定URL。 原先的代码是这样: 

 <form action="/search/" method="get">

  现在改成这样:

 <form action="" method="get">

  action=”“意味着表单将提交给与当前页面相同的URL。 这样修改之后,如果search()视图不指向其它页面的话,你将不必再修改action

简单的验证

  我们的搜索示例仍然相当地简单,特别从数据验证方面来讲;我们仅仅只验证搜索关键值是否为空。 然后许多HTML表单包含着比检测值是否为空更为复杂的验证。 我们都有在网站上见过类似以下的错误提示信息:

  • 请输入一个有效的email地址, foo’ 并不是一个有效的e-mail地址。
  • 请输入5位数的U.S 邮政编码, 123并非是一个有效的邮政编码。
  • 请输入YYYY-MM-DD格式的日期。
  • 请输入8位数以上并至少包含一个数字的密码。

  我们来调整一下search()视图,让她能够验证搜索关键词是否小于或等于20个字符。 (为来让例子更为显著,我们假设如果关键词超过20个字符将导致查询十分缓慢)。那么该如何实现呢? 最简单的方式就是将逻辑处理直接嵌入到视图里,就像这样:

 def search(request):
error = False
if 'q' in request.GET:
q = request.GET['q']
if not q:
error = True
**elif len(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})

  现在,如果尝试着提交一个超过20个字符的搜索关键词,系统不会执行搜索操作,而是显示一条错误提示信息。 但是,search_form.html里的这条提示信息是:”Please submit a search term.”,这显然是错误的, 所以我们需要更精确的提示信息:

 <html>
<head>
<title>Search</title>
</head>
<body>
{% if error %}
<p style="color: red;">Please submit a search term characters or shorter.</p>
{% endif %}
<form action="/search/" method="get">
<input type="text" name="q">
<input type="submit" value="Search">
</form>
</body>
</html>

  但像这样修改之后仍有一些问题。 我们包含万象的提示信息很容易使人产生困惑: 提交一个空表单怎么会出现一个关于20个字符限制的提示? 所以,提示信息必须是详细的,明确的,不会产生疑议。

  问题的实质在于我们只使用来一个布尔类型的变量来检测是否出错,而不是使用一个列表来记录相应的错误信息。 我们需要做如下的调整:

 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) > :
**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模板,现在需要显示一个errors列表而不是一个布尔判断。

 <html>
<head>
<title>Search</title>
</head>
<body>
**{% if errors %}**
**<ul>**
**{% for error in errors %}**
**<li>{{ error }}</li>**
**{% endfor %}**
**</ul>**
**{% endif %}**
<form action="/search/" method="get">
<input type="text" name="q">
<input type="submit" value="Search">
</form>
</body>
</html>

Python框架之Django学习笔记(十六)的更多相关文章

  1. Python框架之Django学习笔记(六)

    模板 上篇博文学习了动态视图,但是,视图中返回文本的方式有点特别. 也就是说,HTML被直接硬编码在 Python 代码之中. def current_datetime(request): now = ...

  2. Python框架之Django学习笔记(十七)

    Django框架之表单(续二) 今天的这篇博客将是Django学习笔记博客的最后一篇,基本每周最少一篇的Django框架学习,坚持到今天也实属不易,当然了,这个框架的学习仅仅是Django框架的基础部 ...

  3. Python框架之Django学习笔记(十一)

    话说上次说到数据库的基本访问,而数据库我们主要进行的操作就是CRUD,也即是做计算处理时的增加(Create).读取(Retrieve)(重新得到数据).更新(Update)和删除(Delete),俗 ...

  4. Python框架之Django学习笔记(十二)

    Django站点管理 十一转眼结束,说好的充电没能顺利开展,反而悠闲的看了电视剧以及去影院看了新上映的<心花路放>.<亲爱的>以及<黄金时代>,说好的劳逸结合现在回 ...

  5. Python框架之Django学习笔记(十)

    又是一周周末,如约学习Django框架.在上一次,介绍了MVC开发模式以及Django自己的MVT开发模式,此次,就从数据处理层Model谈起. 数据库配置 首先,我们需要做些初始配置:我们需要告诉D ...

  6. Python框架之Django学习笔记(十五)

    表单 从Google的简朴的单个搜索框,到常见的Blog评论提交表单,再到复杂的自定义数据输入接口,HTML表单一直是交互性网站的支柱.本次内容将介绍如何用Django对用户通过表单提交的数据进行访问 ...

  7. Python框架之Django学习笔记(十四)

    Django站点管理(续·完) 本想昨天更新的,谁曾想昨天竟然是工作日!我就不吐槽昨天加班到十一点多了,需求增加无疑让我等蛋疼不已,忽而想起一首打油诗: 明月几时有,把酒问群友.不知这次版本,今晚能出 ...

  8. Python框架之Django学习笔记(九)

    模型 之前,我们用 Django 建造网站的基本途径: 建立视图和 URLConf . 正如我们所阐述的,视图负责处理一些主观逻辑,然后返回响应结果. 作为例子之一,我们的主观逻辑是要计算当前的日期和 ...

  9. Python框架之Django学习笔记(五)

    第一个Django网页小结 进来的请求转入/hello/. Django通过在ROOT_URLCONF配置来决定根URLconf. Django在URLconf中的所有URL模式中,查找第一个匹配/h ...

随机推荐

  1. kali linux 系列教程之metasploit 连接postgresql可能遇见的问题

    kali linux 系列教程之metasploit 连接postgresql可能遇见的问题 文/玄魂   目录 kali linux 下metasploit 连接postgresql可能遇见的问题. ...

  2. 限制特定ip访问oracle

    在9i中真正起作用的是sqlnet.ora文件,我们修改sqlnet.ora其实是最好最快的方法. 在sqlnet.ora中增加如下部分 ----------------------------- # ...

  3. HTML5的绘图的支持

    一.简单介绍canvas元素 <canvas.../>是HTML5新增的一个元素,该元素用于绘制图形.实际上<canvas../>只是相当于一张画布. 它除了可以指定通用属性外 ...

  4. java基础之操作符

    一:赋值 1.对基本数据类型的赋值,int a=b:   //把b的值复制给a,如果修改了a的值,b 的值不会受到影响. 2.对引用类型的赋值, public class Text { public ...

  5. linux c socket 并发 服务端

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types. ...

  6. github not authorized eclipse

    eclipse/myeclipse > menu window > preferences > general > security > content >git ...

  7. Flume 读取RabbitMq消息队列消息,并将消息写入kafka

    首先是关于flume的基础介绍 组件名称 功能介绍 Agent代理 使用JVM 运行Flume.每台机器运行一个agent,但是可以在一个agent中包含多个sources和sinks. Client ...

  8. 使用C语言开发PHP扩展(转)

    本篇文章给大家带来的内容是介绍如何使用C语言给PHP写扩展,,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 1.在php源码路径的ext文件夹下,新建一个extend_test.de ...

  9. Linux基础入门-环境变量与文件查找

    一.环境变量: Shell中的变量也有不同的数据类型,不用专门指定类型名,可以参与运算,有作用域限制. declare tmp 创建一个变量 可以不用专门声明,可以即用即创建 tmp=shiyanlo ...

  10. boolalpha的作用

    #include <iostream>using namespace std;int main(){        bool b=true;        cout << &q ...