被解救的Django【6】

使用通用视图:

detail()results()视图都很简单,并且像上面提到的那样,存在冗余问题。用来显示一个议题列表的index() 视图和它们类似。这些视图反映基本的Web开发中的一个常见情况:根据URL中的参数从数据库中获取数据、载入模板文件然后返回渲染后的模板。 由于这种情况非常普遍,Django提供了一种叫做“genericviews”的系统可以方便地进行处理。Genericviews会将常见的模式抽象化,可以使你在编写app时甚至不需要编写Python代码。

让我们将我们的投票应用转换成使用通用视图系统,这样我们可以删除许多我们的代码。我们仅仅需要做以下几步来完成转换:1转换URLconf。2删除一些旧的、不再需要的代码。3 引进基于Django通用视图的新视图。


为什么要重构代码?

一般来说,当编写一个Django应用时,你应该先评估一下通用视图是否可以解决你的问题,你应该在一开始使用它,而不是进行到一半时重构代码。本教程目前为止是有意将重点放在以困难的方式编写视图,这是为将重点放在核心概念上。就像在使用计算器之前你需要知道基本的数学一样。


改良URLconf :

首先,打开polls/urls.py 这个URLconf 并将它修改成:


注意在第二个和第三个模式的正则表达式中,匹配的模式的名字由<question_id> 变成 <pk>


改良视图:

下一步,我们将删除旧的indexdetail results 视图,并用Django的通用视图代替。打开polls/views.py文件,并将它修改成:


我们在这里使用两个通用视图:ListView  DetailView。这两个视图分别抽象显示一个对象列表显示一个特定类型对象的详细信息页面这两种概念。每个通用视图需要知道它将作用于哪个模型, 这由model 属性提供。DetailView期望从URL中捕获名为"pk"的主键值,因此我们把polls/urls.py中question_id改成了pk以使通用视图可以找到主键值。

默认情况下,通用视图DetailView 使用一个叫做<app name>/<model name>_detail.html的模板。在我们的例子中,它将使用 "polls/question_detail.html"模板。template_name属性是用来告诉Django使用一个指定的模板名字,而不是自动生成的默认名字。 我们也为results列表视图指定了template_name —— 这确保results视图和detail视图在渲染时具有不同的外观,即使它们在后台都是同一个 DetailView


类似地,ListView使用一个叫做<app name>/<model name>_list.html的默认模板;我们使用template_name 来告诉ListView 使用我们自己已经存在的"polls/index.html"模板。在之前的教程中,提供模板文件时都带有一个包含question 和 latest_question_list 变量的context。对于DetailView ,question变量会自动提供—— 因为我们使用Django 的模型(Question), Django 能够为context变量决定一个合适的名字。然而对于ListView,自动生成的context变量是question_list。为了覆盖这个行为,我们提供 context_object_name 属性,表示我们想使用latest_question_list。作为一种替换方案,你可以改变你的模板来匹配新的context变量 —— 但直接告诉Django使用你想要的变量会省事很多。


自动化测试


polls文件下有默认的tests.py文件,该文件是进行自动化测试脚本的。应用的测试用例按惯例一般放在该应用的tests.py文件中;测试系统将自动在任何以test开头的文件中查找测试用例。 






发生了如下这些事:python manage.py test polls查找polls 应用下的测试用例,它找到 django.test.TestCase 类的一个子类,它为测试创建了一个特定的数据库,它查找用于测试的方法——名字以test开始,它运行test_was_published_recently_with_future_question创建一个pub_date为未来30天的 Question实例,然后利用assertEqual()方法,它发现was_published_recently() 返回True,尽管我们希望它返回False。这个测试通知我们哪个测试失败,甚至是错误出现在哪一行。


修复错误

我们已经知道问题是什么:如果它的pub_date是在未来,Question.was_published_recently() 应该返回 False。在models.py中修复这个方法,让它只有当日期是在过去时才返回True 

polls/models.py




在找出一个错误之后,我们编写一个测试来暴露这个错误,然后在代码中更正这个错误让我们的测试通过。未来,我们的应用可能会出许多其它的错误,但是我们可以保证我们不会无意中再次引入这个错误,因为简单地运行一下这个测试就会立即提醒我们。 我们可以认为这个应用的这一小部分会永远安全了。

更加综合的测试

在这里,我们可以使was_published_recently() 方法更加稳定;事实上,在修复一个错误的时候引入一个新的错误将是一件很令人尴尬的事。在同一个类中添加两个其它的测试方法,来更加综合地测试这个方法:

polls/tests.py

现在我们有三个测试来保证无论发布时间是在过去、现在还是未来 Question.was_published_recently()都将返回合理的数据。再说一次,polls 应用虽然简单,但是无论它今后会变得多么复杂以及会和多少其它的应用产生相互作用,我们都能保证我们刚刚为它编写过测试的那个方法会按照预期的那样工作。


测试一个视图

这个投票应用没有区分能力:它将会发布任何一个Question,包括 pub_date字段位于未来。我们应该改进这一点。 设定pub_date在未来应该表示Question在未来发布,但是直到那个时间点才会变得可见。

视图的一个测试

当我们修复上面的错误时,我们先写测试,然后修改代码来修复它。 事实上,这是测试驱动开发的一个简单的例子,但做的顺序并不真的重要。在我们的第一个测试中,我们专注于代码内部的行为。 在这个测试中,我们想要通过浏览器从用户的角度来检查它的行为。在我们试着修复任何事情之前,让我们先查看一下我们能用到的工具。

Django测试客户端

Django提供了一个测试客户端来模拟用户和代码的交互。我们可以在tests.py 甚至在shell 中使用它。我们将再次以shell开始,但是我们需要做很多在tests.py中不必做的事。首先是在 shell中设置测试环境:



自定义你的应用的外观

首先在你的polls中创建一个static目录。Django将在那里查找静态文件,这与Djangopolls/templates/中寻找对应的模板文件的方式是一致的。Django  STATICFILES_FINDERS 设置包含一个查找器列表,它们知道如何从各种源找到静态文件。 其中默认的一个是AppDirectoriesFinder,像在刚刚polls中创建的那个项目查找方式一样,它会在每个INSTALLED_APPS下查找“static”子目录,。管理站点也为它的静态文件使用相同的目录结构。在你刚刚创建的static目录中,创建另外一个目录polls并在它下面创建一个文件style.css。换句话讲,你的样式表应该位于polls/static/polls/style.css。因为AppDirectoriesFinder 静态文件查找器的工作方式,你可以通过polls/style.cssDjango中访问这个静态文件,与你如何访问模板的路径类似。


将下面的代码放入样式表中 (polls/static/polls/style.css)

polls/static/polls/style.css

li a {

    color: white;

}

下一步,在polls/templates/polls/index.html的顶端添加如下内容

polls/templates/polls/index.html

{% load staticfiles%}

 

<linkrel="stylesheet" type="text/css" href="{% static'polls/style.css' %}" />


添加一张背景图片

下一步,我们将创建一个子目录来存放图片。 polls/static/polls/目录中创建一个 images 子目录。在这个目录中,放入一张图片background.gif。换句话,将你的图片放在 polls/static/polls/images/background.gif

然后,向你的样式表添加(polls/static/polls/style.css):

polls/static/polls/style.css

body {

    background: whiteurl("images/background.gif") no-repeat right bottom;

}

重新加载http://localhost:8000/polls/,你应该在屏幕的右下方看到载入的背景图片。












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值