• Django学习系列12:把Python变量传入模板中渲染


    从视图的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),  # 5
                "New to-do item did not appear in table -- its text was:
    %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:
    %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  # 4
    import time
    import unittest
    
    class NewVisitorTest(unittest.TestCase):
        def setUp(self):  # 1
            self.browser = webdriver.Firefox()
            self.browser.implicitly_wait(3)
    
        def tearDown(self):  # 1
            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   # 2
            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']
  • 相关阅读:
    ubuntu没有权限(不能)创建文件夹(目录)
    在ubuntu下安装KDE以及完全卸载KDE
    RadASM的主题更换!
    RadASM的测试工程!
    RadASM的测试工程!
    汇编工具安装三:已经配置好的汇编开发工具!
    汇编工具安装三:已经配置好的汇编开发工具!
    OSI 七层模型和 TCP/IP 四层模型 及 相关网络协议
    LwIP
    神秘的40毫秒延迟与 TCP_NODELAY
  • 原文地址:https://www.cnblogs.com/ranxf/p/11676687.html
Copyright © 2020-2023  润新知