前言
自己动手丰衣足食
之前在 思否 提了这个问题,但是没人回答啊,那就只能自己解决了!
不仅仅是思否,stackoverflow 不过都没有人回答
如何输出 SQL 语句
在项目的 settings.py
文件中添加如下内容就可以将一切对数据库的操作翻译为 SQL
语句,但是注意这个模式只有在 settings.py
中的 DEBUG
开关为 True
是才有效!
1 | python复制代码LOGGING = { |
在单元测试中输出 SQL 语句的需求
上面的语句在做单元测试的时候就变得不好使!
根本就不输出 SQL
语句!!!
我一开始以为是上面代码中的 level
设置的不对,应该将 DEBUG
改为 生产,当然,答案并非如此!
找寻答案
为什么会有这个需求呢?其实还是为了调试代码方便嘛,但既然是调试代码,如果涉及数据库的操作却不输出 SQL
语句,就感觉是雾里看花、黑箱操作让人摸不着头脑!!!作为一名优秀的程序员怎么能允许这种事情发生呢?当然不可以!!!
所以我去通读了 Django
官方文档中相关的内容
通过阅读改文档可知:做单元测试的时候会以生产模式运行,这就解释了为什么不输出 SQL 语句,因为我们的日志设置的级别是 DEBUG
无论配置文件中的
DEBUG
设置值是多少,所有的 Django 测试都以DEBUG
=False 运行。这是为了确保你的代码观察到的输出与生产环境下的输出一致。
好的,找到了改进方向了,那就 level
改为生产模式就好了嘛!
但是通过阅读文档发现只有:
+ `DEBUG`:排查故障时使用的低级别系统信息
+ `INFO`:一般的系统信息
+ `WARNING`:描述系统发生了一些小问题的信息
+ `ERROR`:描述系统发生了大问题的信息
+ `CRITICAL`:描述系统发生严重问题的信息这五种模式,最低就是 DEBUG,根本没有生产模式啊!!!
读完该篇文档,我懂了,之前想要修改 level
的想法是错误的,我们可以也应该通过自定义测试器 的方式来让单元测试也输出 SQL 语句!!!
说干就干!
说干就干
在根目录下面新建一个 testing 文件夹,然后在其中创建一个 testcases.py 文件,在其中写下如下的代码:
1 | python复制代码from django.test.runner import DiscoverRunner |
这段代码有几个关键点
- 继承
DiscoverRunner
这个没什么好说的,默认就是 DiscoverRunner
,所以我们继承他
- debug_sql=True, verbosity=2
继承它不为别的,就像开启上面的两个参数
testing
和testcases.py
这些名字随意,只是我习惯这么放置和取名字,你随意!!!
然后再 settings.py
文件中的任意位置添加下面的代码:
1 | python复制代码TEST_RUNNER = 'testing.testrunner.DebugDiscoverRunner' |
这个时候你只需要再终端输入
1 | bash复制代码python manage.py test |
就会调用我们的 DebugDiscoverRunner
来做单元测试,执行 __init__.py
传递 debug_sql=True, verbosity=2
,就会再控制台源源不断的打印 SQL 语句!!!
一些细节
你会发现 DebugDiscoverRunner
的 __init__.py
传递给 super().__init__(debug_sql=True, verbosity=2)
的参数没有了 *args, **kwargs
,为什么呢?
因为会报错!!!
如下:
1 | bash复制代码vagrant@vagrant:/vagrant$ python manage.py test comments |
参考文章:Django:DiscoverRunner覆盖引发错误
参考归参考,但是这个人的处理方法很不好
所以我们去掉了 *args, **kwargs
本文转载自: 掘金