1、前言
在做 django 开发需求时,多多少少都会遇到需要定时任务的功能,比如定时执行任务,检查订单之类的。可能是一段时间,比如每隔 10分钟执行一次,也可能是定点时间,比如 14:00 执行,也可能是长时间,比如每周几,每个月的哪一天等。查看了一下相关资料, django 定时任务 django-crontab
库比较多教程和资料,虽然 star 数才五百,但是 API 接口比较简单,接入也很方便,功能也很全面,当然,也存在一此无法解决的问题,使用时需要注意的。
2、使用教程
1.安装:
1 | pip install django-crontab |
2.添加配置到 settings.py INSTALLED_APPS
中
1 | INSTALLED_APPS = ( |
3.编写定时函数:
定时任务可以分成两种,一种是执行自定义的
mange.py
的命令,另一种是执行自定义函数。
在django的app中新建一个myapp/cron.py文件,把需要定时执行的代码放进去
示例:
1 | def my_scheduled_job(): |
4.在 settings.py 中增加CRONJOBS
配置
1 | CRONJOBS = [ |
也可以定义一些关键字参数,有2种格式:
格式1:
- 要求:cron计时通常格式(有关更多示例,请参阅 Wikipedia 和 crontab.guru)
- 要求:python模块路径下待执行定时任务
- 可选:特定于定时任务的后缀(例如,将
out/err
重定向到文件,默认值为’’)
示例:
1 | CRONJOBS = [ |
注意: >>
表示追加写入,>
表示覆盖写入。
格式2:
- 要求:cron计时通常格式
- 要求:python模块路径下待执行定时任务
- 可选:方法的位置参数列表(默认值:[])
- 可选:方法的关键字参数的dict(默认值:{})
- 可选:特定于定时任务的后缀(例如,将
out/err
重定向到文件,默认值为’’)
示例:
1 | CRONJOBS = [ |
对于熟悉 Linux 中定时任务crontab
的同学可能对上面第一个参数的语法很亲切。上面表示每隔1分钟执行一次代码。
Linux 中的定时任务crontab
的语法如下:
1 | * * * * * command |
有几个特殊的符号:
1 | * 代表所有的取值范围的数字 |
示例:
1 | 每两个小时 0 */2 * * * |
1 | 0 6 * * * commands >> /tmp/test.log # 每天早上6点执行, 并将信息追加到test.log中 |
有兴趣的小伙伴可以深入研究下 Linux 的crontab
定时任务。如果不了解和不熟悉可以想看: cron语法格式学习
5.添加并启动定时任务
1 | #添加并启动定时任务 |
其它命令:
1 | #显示当前的定时任务 |
一些问题
输出到日志的默认是不支持日志的,所以可以 settings.py 中设置中文支持:
1 | CRONTAB_COMMAND_PREFIX = ‘LANG_ALL=zh_cn.UTF-8’ |
如果配置成这样:
1 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
上述代码的目的是,希望对任务的输出和错误日志,进行 log_ddmmYY
格式进行文件每天分开保存。
但是这个任务,在第二天时,就不会在执行啦!!
因为,CRONJOBS
生成任务时,会生成对应的哈希值(hashes),标识每个任务。所以,当文件名变更时,CRONJOBS
中的值每天都在变化,导致不同的定时任务哈希值(hashes)。
针对这种情况,解决方法是,日志文件名称固定,然后创建一个任务,用来每天把日志文件重命名(move)成想要的格式名称,这样就可以啦!
2020-09-13 更新
由于最新的 macOS 10.15 后系统对访问文件夹目录权限做了限制,默认是不允许读写文件。所以导致了一些bug。所以,执行定时任务时,如果出错,默认是不会写到日志文件里的,那么排查错误呢?
在 settings.py 中增加CRONTAB_COMMAND_SUFFIX
配置:
1 | CRONTAB_COMMAND_SUFFIX = ‘2>&1’ |
增加了这个配置,那么错误的日志也会直接输出到配置的日志文件中。
当然,也可以在 settings.py 中的CRONJOBS
配置中指定错误日志输出的文件目录,例如:
1 | CRONJOBS = [ |
另外,可以通过下面2个命令查看 crontab
具体的任务:
1 | crontab -l |
输出错误后,就可以根据错误的问题,找到原因后解决了。
总结
通过这个需求,可以看到很多知识点其实是串联起来的,从python
到django
到Linux
的crontab
,所以,学习无止境,知识学习只会越来越多,如果你提前掌握了某些知识,那么学习新(旧)知识的成本就会降低很多,或者理解成本,比如你学习了 Linux
, 了解过 cron
,那么对于学习这个 django
的定时任务会轻松很多!永远不要认为有些知识你永远用不上,所以现在就不学,可能现在的永远距离已经很短啦!加油~
参考
- kraiz/django-crontab: dead simple crontab powered job scheduling for django.
- django开发-定时任务的使用 - wyzane - SegmentFault 思否
- django-crontab 定时执行任务方法 - 程序园
- django-crontab实现Django定时任务
- django使用django-crontab实现定时任务 - 简书
- 使用django-crontab实现定时任务 - 腾讯云
- cron语法格式学习 - 简书
- django-crontab is missing job hash after one day · Issue #76 · kraiz/django-crontab
- Cron Format - Wikipedia
- crontab.guru
- python - 的Django的crontab不执行测试功能
- python - PermissionError: Errno 1 Operation not permitted: ‘/Users/
/venv/pyvenv.cfg’ - Stack Overflow - python - Django crontab not executing test function - Stack Overflow
- 解决mac osx下pip安装ipython权限的问题 – 峰云就她了
- 如何在Django中开启一个定时任务_qq_15256443的博客-CSDN博客
- 如有疑问,欢迎在评论区一起讨论!
- 如有不正确的地方,欢迎指导!
> 注:本文首发于 [iHTCboy's blog](https://iHTCboy.com),如若转载,请注来源