从视图的Python代码中把变量传入HTML模板。

模板中使用哪种句法引入Python对象,要使用的符号{{...}},它会以字符串的形式显示对象:

<html>
<head>
<title>To-Do lists</title>
</head>>
<body>
<h1>Your To-Do list</h1>
<form method="POST">
<input name="item_text" id="id_new_item" placeholder="Enter a to-do item" />
{% csrf_token %}
</form> <table id="id_list_table">
<tr><td>{{ new_item_text}}</td></tr>
</table>
</body>
</html>

怎么测试视图函数为new_item_text传入的值正确呢?怎么把变量传入模板呢?

可以在单元测试中实际操作一遍找出这两个问题的答案。(前面我们用到了render_to_string函数,用它手动渲染模板,然后拿它的返回值和视图函数返回的HTML比较)

让我们调整单元测试,以便它检查我们是否仍在使用模板:

lists/tests.py

    def test_can_save_a_post_request(self):
response = self.client.post('/', data={'item_text':'A new list item'})
self.assertIn('A new list item', response.content.decode())
self.assertTemplateUsed(response, 'home.html')

如预期那样失败:

AssertionError: No templates used to render the response

很好,我们故意编写愚蠢的返回值已经骗不过我们的测试,因此要重写视图函数,把post请求中的参数传递给模板。render函数将映射模板的字典作为其第三个参数变量名到其值:

lists/views.py

from django.shortcuts import render
from django.http import HttpResponse # Create your views here.在这儿编写视图
def home_page(request):
return render(request, 'home.html', {
'new_item_text':request.POST['item_text'],
})

运行单元测试

django.utils.datastructures.MultiValueDictKeyError: "'item_text'"

这次失败发生在另一个测试中,修正的方法如下:

lists/views.py

from django.shortcuts import render
from django.http import HttpResponse # Create your views here.在这儿编写视图
def home_page(request):
return render(request, 'home.html', {
'new_item_text': request.POST.get('item_text', ''),
})

单元测试通过

看看功能测试结果:

AssertionError: False is not true : New to-do item did not appear in table 

错误信息没有多大帮助,使用另一种功能测试的调试技术:改进错误信息。

#  functional_tests.py

        self.assertTrue(
any(row.text == '1: Buy peacock feathers' for row in rows), #
"New to-do item did not appear in table -- its text was:\n%s" % (
table.text,
)

改进后,测试给出了更有用的错误信息

AssertionError: False is not true : New to-do item did not appear in table -- its text was:
Buy peacock feather

怎么改效果更好,让断言不那么灵巧。把六行assertTrue换成一行assertIn:

        # self.assertTrue(
# any(row.text == '1: Buy peacock feathers' for row in rows), # 5
# "New to-do item did not appear in table -- its text was:\n%s" % (
# table.text,
# )
# )
self.assertIn('1: Buy peacock feathers', [row.text for row in rows])

修改后得到以下错误信息:(错误的意思是功能测试在枚举列表中的项目时希望第一个项目以“1:开头”。)

    self.assertIn("1:Buy peacock feathers", [row.text for row in rows])
AssertionError: '1:Buy peacock feathers' not found in ['Buy peacock feather']

让测试通过最快的方法是修改模板

            <tr><td>1:{{ new_item_text}}</td></tr>

现在功能测试能执行到self.fail。

如果扩充功能测试,检查表格中添加的第二个待办事项(复制粘贴),我们会发现刚才使用的简单处理方法不奏效了。

        # 页面再次更新,清单中显示了这两个待办事项
inputbox.send_keys(Keys.ENTER)
time.sleep(1) table = self.browser.find_element_by_id('id_list_table')
rows = table.find_elements_by_tag_name('tr')
self.assertIn('1: Buy peacock feathers', [row.text for row in rows])
self.assertIn('2: Use peacock feathers to make a fly', [row.text for row in rows]) self.fail("完成测试")
# self.assertIn('Django', self.browser.title)

这个功能测试会返回一个错误

AssertionError: '2: Use peacock feathers to make a fly' not found in ['1: Buy peacock feathers']

代码提交:

$ git diff
# should show changes to functional_tests.py, home.html, tests.py and views.py
$ git commit -am “添加两个待办事项清单”

然后重构功能测试。使用辅助方法(放在tearDown和第一个测试之间),记住名字以test_开头的方法才会作为测试运行,可以根据需求使用其他方法,下面在功能测试中使用辅助方法

from selenium import webdriver
from selenium.webdriver.common.keys import Keys #
import time
import unittest class NewVisitorTest(unittest.TestCase):
def setUp(self): #
self.browser = webdriver.Firefox()
self.browser.implicitly_wait(3) def tearDown(self): #
self.browser.quit() def check_for_row_in_list_table(self, row_text):
table = self.browser.find_element_by_id('id_list_table')
rows = table.find_elements_by_tag_name('tr')
self.assertIn(row_text, [row.text for row in rows])
# 伊迪丝听说了一个很酷的在线待办事项应用程序。她去看看它的主页
# Edith has heard about a cool new online to-do app. She goes to check out its homepage
def test_start_a_list_and_retrieve_it_later(self):
self.browser.get('http://localhost:8000') # 她注意到网页的标题和头部都包含“Django”.She notices the page title and header mention to-do lists
self.assertIn('To-Do', self.browser.title)
header_text = self.browser.find_element_by_tag_name('h1').text #
self.assertIn('To-Do', header_text) # 应用邀请她输入一个待办事项 She is invited to enter a to-do item straight away
inputbox = self.browser.find_element_by_id('id_new_item')
self.assertEqual(
inputbox.get_attribute('placeholder'),
'Enter a to-do item'
) # 她在一个文本框中输入了“buy peacock feathers(购买孔雀羽毛)”,她的爱好时用假蝇做鱼饵钓鱼
inputbox.send_keys('Buy peacock feathers') # 页面再次更新,清单中显示了这两个待办事项
inputbox.send_keys(Keys.ENTER)
time.sleep(1)
self.check_for_row_in_list_table('1: Buy peacock feathers') # 页面中又显示了一个文本框,可以输入其他的待办事项
inputbox = self.browser.find_element_by_id('id_new_item')
inputbox.send_keys('Use peacock feathers to make a fly')
inputbox.send_keys(Keys.ENTER)
time.sleep(1) # 页面再次更新,她的清单中显示了这两个待办事项
self.check_for_row_in_list_table('1: Buy peacock feathers')
self.check_for_row_in_list_table('2: Use peacock feathers to make a fly') self.fail("完成测试")
# self.assertIn('Django', self.browser.title)

再次运行功能测试,看重构前后的表现是否一致:

AssertionError: '1: Buy peacock feathers' not found in ['1: Use peacock feathers to make a fly']

Django学习系列12:把Python变量传入模板中渲染的更多相关文章

  1. Django学习系列之Form基础

     Django学习系列之Form基础 2015-05-15 07:14:57 标签:form django 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追 ...

  2. Caffe学习系列(12):训练和测试自己的图片--linux平台

    Caffe学习系列(12):训练和测试自己的图片   学习caffe的目的,不是简单的做几个练习,最终还是要用到自己的实际项目或科研中.因此,本文介绍一下,从自己的原始图片到lmdb数据,再到训练和测 ...

  3. django学习系列——python和php对比

    python 和 php 我都是使用过,这里不想做一个非常理性的分析,只是根据自己的经验谈一下感想. 在web开发方面,无疑 php 更甚一筹. 从某种角度来说,php 就是专门为 web 定制的语言 ...

  4. Python&Django学习系列之-激活管理界面

    1.创建你个人的项目与APP 2.填写你的数据库名称与数据库类型,这里使用内置的sqllite3 3.修改setting文件 a.将'django.contrib.admin'加入setting的IN ...

  5. Django学习(1)——python manage.py startapp app-name新建app报错问题

    作为一个刚接触python的小白,开始学习Django注定前路漫漫,记录一下学习过程中的问题和解决方案. 感谢“自强学堂”的无私奉献,根据教程安装了Django 1.9.12后,尝试新建项目,此时使用 ...

  6. Django学习系列之模板系统

    一.模板标签 if/else {%  if  %}标签检查一个变量的值是否为真或者等于另外一个值,如果为真,系统会执行{%  if  %}和{%  endif  %}之间的代码块,例如: {% if ...

  7. Django学习系列之模板

    什么是django模板 模板是一个文本,用于分离文档的表现形式和内容,模板定义了占位符以及各种用于规范文档该如何显示的各部分基本逻辑(模板标签) 模板通常用于产生HTML 如何使用模板 创建一个Tem ...

  8. Django学习系列6:使用selenium测试用户交互

    学习系列5中的单元测试有报错信息,这儿来编写functional_tests.py文件,扩充其中的功能测试 # File: functional_test.py # Author: Rxf # Cre ...

  9. Python零基础学习系列之二--Python介绍及环境搭建

    1-1.Python简介: Python是一种解释型.面向对象.动态数据类型的高级程序设计语言.Python由Guido van Rossum于1989年底发明,第一个公开发行版发行于1991年.像P ...

随机推荐

  1. Vuex的认识和简单应用(一)

    一.vuex是一个专为vue.js应用程序开发的状态管理模式. 应用场景:1.多个视图依赖于同一个状态2.来自不同视图的行为需要变更同一个状态此时,我们可以把组件的共享状态抽取出来,以一个全局单例模式 ...

  2. Linux批量文件管理

    Linux批量文件管理   实验目标: 通过本实验掌握批量建立.移动.复制文件或目录的操作,也可以作为后续shell编程的基础. 实验步骤: 1.现在有十台终端机器,要为每台机器建立3个文件,总共要建 ...

  3. U盘安装Ubuntu Server CD-ROM挂载失败

    U盘安装 Ubuntu Server 发生Failed to copy file from CD-ROM问题 使用UltraISO制作Ubuntu Server安装盘,在安装过程中出现[!!] Loa ...

  4. LINQ查询表达式详解(2)——查询表达式的转换

    简介 C#在执行LINQ查询表达式的时候,并不会指定其执行语义,而是将查询表达式转换为遵循查询表达式模式的方法的调用.具体而言,查询表达式将转换为以下名称的调用:Where.Select.Select ...

  5. MySQL 中 savepoint 的使用

     介绍 savepoint 结点名; # 设置保存点,并和rollback结合使用,实现回滚到指定保存点 rollback to 结点名; # 回滚到指定点 样例演示 USE human; ; sta ...

  6. 【扩展GCD】荒岛野人

    题目 [题目描述] 克里特岛以野人群居而著称.岛上有排列成环行的M个山洞.这些山洞顺时针编号为1,2,-,M.岛上住着N个野人,一开始依次住在山洞C1,C2,-,CN中,以后每年,第i个野人会沿顺时针 ...

  7. C++笔记(3)——string.h相关的一些小知识

    strlen() 用于得到字符数组中第一个\0前的字符的个数,格式如下: strlen(数组); 例子: #include <stdio.h> #include <string.h& ...

  8. 双01字典树最小XOR(three arrays)--2019 Multi-University Training Contest 5(hdu杭电多校第5场)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6625 题意: 给你两串数 a串,b串,让你一一配对XOR使得新的 C 串字典序最小. 思路: 首先这边 ...

  9. spark教程(14)-共享变量

    spark 使用的架构是无共享的,数据分布在不同节点,每个节点有独立的 CPU.内存,不存在全局的内存使得变量能够共享,驱动程序和任务之间通过消息共享数据 举例来说,如果一个 RDD 操作使用了驱动程 ...

  10. Spring的事务传播机制实例 (转)

    1,Propagation.REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中.详细解释在代码下方. 实例 员工service @Service public ...