Django 中的 csrf_token 与单元测试
Django 中的 csrf_token 与单元测试
在《Python Web开发:测试驱动方法》一书中作者使用的 Django 版本是 1.7,而我使用的是1.9.7版(官网已经更新到1.10了)。这就导致书中给出的代码可能有“过时”的部分。
比如,下面是第三章一个单元测试tests.py
的代码,运行没有问题。但是当第五章引入表单后,相应模板中需在<form>
标签内加入CSRF令牌{% csrf_token %}
。此时再次运行此单元测试会报错。
from django.test import TestCase
from django.core.urlresolvers import resolve
from django.http import HttpRequest
from django.template.loader import render_to_string
from .views import home_page
class HomePageTest(TestCase):
def test_root_url_resolves_to_home_page_view(self):
found = resolve('/')
self.assertEqual(found.func, home_page)
def test_home_page_returns_correct_html(self):
request = HttpRequest()
response = home_page(request)
expected_html = render_to_string('home.html')
self.assertEqual(response.content.decode(), expected_html)
错误信息:
$ python3 manage.py test lists
Creating test database for alias 'default'...
F.
======================================================================
FAIL: test_home_page_returns_correct_html (lists.tests.HomePageTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/panzeyan/PycharmProjects/TDD/superlists/lists/tests.py", line 20, in test_home_page_returns_correct_html
self.assertEqual(response.content.decode(), expected_html)
AssertionError: '<htm[240 chars] <input type=\'hidden\' name=\'csrfmiddlew[184 chars]l>\n' != '<htm[240 chars] \n </form>\n\n <table id="i[87 chars]l>\n'
----------------------------------------------------------------------
Ran 2 tests in 0.256s
FAILED (failures=1)
Destroying test database for alias 'default'...
根据错误信息,是最后一行的断言self.assertEqual(response.content.decode(), expected_html)
导致测试失败。
由于AssertionError
信息显示不完整,所以将该行断言注释掉,添加2行代码,打印出response.content.decode()
和 expected_html
的全部内容。
print('response.content.decode()\n', response.content.decode())
print('expected_html\n', expected_html)
运行测试:
$ python3 manage.py test lists
Creating test database for alias 'default'...
response.content.decode()
<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" />
<input type='hidden' name='csrfmiddlewaretoken' value='tl2rZy1RBSLY75DD2ysZ4KHF0DePGWQs' />
</form>
<table id="id_list_table">
<tr><td>1: </td></tr>
</table>
</body>
</html>
expected_html
<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" />
</form>
<table id="id_list_table">
<tr><td>1: </td></tr>
</table>
</body>
</html>
..
----------------------------------------------------------------------
Ran 2 tests in 0.015s
OK
Destroying test database for alias 'default'...
在渲染模板时,Django 会把这个模板标签替换成一个<input type="hidden">
元素,其值是CSRF 令牌。
从上面的html代码可以看出,通过视图函数home_page()
渲染得到的响应包含csrf转换的<input>
元素,而render_to_string()
则未生成该部分,所以导致测试失败。
以 “django csrf_token 测试”为关键字google下,发现已经有人碰到这个问题。可惜代码不全,网页中提到的参考链接已经失效。
再以失效链接中的“django-csrf_token-when-using-render_to_string”为关键词google,stackoverflow上有人给出一个简单的解决方法,在tests.py
中的render_to_string()
函数内中加一个参数
expected_html = render_to_string('home.html', request=request)
运行测试,不再报错,问题解决。
$ python3 manage.py test lists
Creating test database for alias 'default'...
..
----------------------------------------------------------------------
Ran 2 tests in 0.012s
OK
Destroying test database for alias 'default'...
Django 中的 csrf_token 与单元测试的更多相关文章
- django中写form表单时csrf_token的作用
之前在学习django的时候,在template中写form时,出现错误.百度,google后要加{% csrf_token %}才可以,之前一直也没研究,只是知道要加个这个东西,具体是什么也不明白. ...
- Python单元测试简介及Django中的单元测试
Python单元测试简介及Django中的单元测试 单元测试负责对最小的软件设计单元(模块)进行验证,unittest是Python自带的单元测试框架. 单元测试与功能测试都是日常开发中必不可少的部分 ...
- django中csrf_token处理方式
第一:先在HTML中加入{% csrf_token %} $.ajax({ url: '{% url "ceshi:list" %}', type: 'post', dataTyp ...
- django中tinymce添加图片上传功能
主要参考以下: https://pixabay.com/en/blog/posts/direct-image-uploads-in-tinymce-4-42/ http://blog.csdn.net ...
- Django中csrf错误
CSRF(Cross-site request forgery)跨站请求伪造,也被称为“one click attack”或者session riding,通常缩写为CSRF或者XSRF,是一种对网站 ...
- Django中的CSRF
CSRF(Cross Site Request Forgery, 跨站域请求伪造) CSRF 背景与介绍 CSRF(Cross Site Request Forgery, 跨站域请求伪造)是一种网络的 ...
- Django中使用ModelForm实现Admin功能
接上一篇<Django中使用Bootstrap> ModelForm 可以将数据库中的信息展示在一个表中,因此我们在查询数据库信息时可以使用ModelForm在前端展示查询到的信息. 在上 ...
- Django中的Form表单
Django中已经定义好了form类,可以很容易的使用Django生成一个表单. 一.利用Django生成一个表单: 1.在应用下创建一个forms文件,用于存放form表单.然后在forms中实例华 ...
- Django中的ORM
Django中ORM的使用. 一.安装python连接mysql的模块:MySQL-python sudo pip install MySQL-python 安装完成后在python-shell中测试 ...
随机推荐
- [USACO5.5]隐藏口令Hidden Password [最小表示法模板]
最小表示法就是一个字符串构成一个环,找以哪个点为开头字典序最小. 然后我们就可以用n2的算法愉快的做啦~实际上有O(n)的做法的,就是用两个指针扫,如果这两个位置的字典序相等,就一起往后,如果某一个大 ...
- 46.object类型
主要知识点 1.field分类 2.object field类型的存储 一.field类型分类 1.multivalue field { "tags": [ "tag1& ...
- Silverlight之我见——制作星星闪烁动画
圣诞节来了,无聊,做点东西纪念一下. 原理很简单,生成1000个圆,从随机数来布置它们的位置,通过动画来处理它们的透明度,动画时长也是随机生成. 1.创建图形数组并设置背景透明,渐变笔触,大小等,而后 ...
- lunix下的redis数据库操作——hash(哈希)
哈希,形如:key : (field : value) 创建:(可以理解为users用户,name为xxx) hset users name xxx 查看: hget users name # &qu ...
- 【习题 4-6 UVA - 508】Morse Mismatches
[链接] 我是链接,点我呀:) [题意] 给你每个字母对应的摩斯密码. 然后每个单词的莫斯密码由其组成字母的莫斯密码连接而成. 现在给你若干个莫斯密码. 请问你每个莫斯密码对应哪个单词. 如果有多个单 ...
- 0816关于MySQL的审计 init-connect+binlog实现用户操作追踪
转自:http://blog.sina.com.cn/s/blog_605f5b4f01013xkv.html mysql 用init-connect+binlog实现用户操作追踪 做access 的 ...
- jquery-cookie持久化
jQuery.Cookie.js,是一个轻量级的Cookie管理插件 <script src="jQuery.1.8.3.js" type="text/javasc ...
- [bzoj3717][PA2014]Pakowanie_动态规划_状压dp
Pakowanie bzoj-3717 PA-2014 题目大意:给你n个物品m个包,物品有体积包有容量,问装下这些物品最少用几个包. 注释:$1\le n\le 24$,$1\le m\le 100 ...
- 关于JOS 未对全部内存分页映射之前 物理地址映射问题的思考
在kern/pmap.c 里面会又以下这段代码,要知道boot_alloc只会分配线性地址,真正建立虚拟页和物理页映射关系的在后面的page_alloc. ////////////////////// ...
- 2015多校联合训练赛 hdu 5308 I Wanna Become A 24-Point Master 2015 Multi-University Training Contest 2 构造题
I Wanna Become A 24-Point Master Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 ...