服务端处理表单提交 - yann学长的运维开发指南28

in #devops8 years ago

说明

目前的进度及后续的课程
http://www.iamyann.com/images/20180508163521.png
(html comment removed: more)

介绍

今天的内容是服务端处理POST请求及模板渲染.

今天的具体内容如下:

  • 服务端处理提交的请求
  • 构造正确的结果
  • 把变量传入模板渲染
  • 测试使用模板
  • 更新视图模块

服务端处理提交的请求

复习一下之前的知识, form表单提交之后,会有一个action属性
如果没有指定属性的话,提交后会返回之前的页面,这样往往是有问题的
解决这个问题之前,先把测试文件写出来

vi  lists/tests.py
def test_uses_home_template(self):
    response = self.client.get('/')
    self.assertTemplateUsed(response, 'home.html')


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

在HomePageTest类新加一个方法,检查POST后返回的是否html文件中是否有目标字段

python manage.py test
AssertionError: 'A new list item' not found in '<html>\n    <head>\n'

提示没有找到提交的字段,显示的内容是首页的, 首页只有To-Do字样,测试看起来是正确的

构造正确的结果

暂时修改下视图模块,给一个期待的反馈

vi lists/views.py
from django.http import HttpResponse
from django.shortcuts import render

def home_page(request):
    if request.method == 'POST':
        return HttpResponse(request.POST['item_text'])
    return render(request, 'home.html')

如果遇到POST的方法,直接把提交的字符串返回回去
这样测试是通过了,但也就没有测试应有的用途了

把变量传入模板渲染

lists/templates/home.html
<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>

在模板上写一个表格,来放传过来的字符串

测试使用模板

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

增加模板测试内容,然后测试

python manage.py test
AssertionError: No templates used to render the response

因为视图函数没有使用模板,所以测试失败,这样就排除了之前"作弊"的内容

更新视图模块

lists/views.py
def home_page(request):
    return render(request, 'home.html', {
        'new_item_text': request.POST['item_text'],
    })

更新试图内容,然后测试

python manage.py test

ERROR: test_uses_home_template (lists.tests.HomePageTest)
[...]
  File "...python-tdd-book/lists/views.py", line 5, in home_page
    'new_item_text': request.POST['item_text'],
[...]
django.utils.datastructures.MultiValueDictKeyError: "'item_text'"

意外故障出现,这是request.Post/Get 时,提取的 Key 不存在导致

lists/views.py
def home_page(request):
    return render(request, 'home.html', {
        'new_item_text': request.POST.get('item_text', ''),
    })

更新,修改了获取的方法

预告

折腾了这么就,单元测试终于通过了,下一节会和功能测试做斗争

回顾一下,这已经是第28篇文章了, 坚持了几个月,但是最近越来越没动力,偶然间读了下自己的文章,感觉代入感不强,也许,代码还是应该回归电脑之前,在手机端解释代码的做法还是有些愚笨,还有3期,我也在孕量修改,到30期应该会有一个大的变化.

http://hero.iamyann.com/blog_webchat.jpg