自学Python第二十二天- Django框架(六) django的实用插件:cron、APScheduler

django-crontab 和 django-cron

有时候需要django在后台不断的执行一个任务,简单的可以通过中间件来实现,但是中间件是根据请求触发的。如果需要定时执行任务,则需要使用到一些插件。

django-crontab 和 django-cron 是常用的用于处理定时任务的插件库,两者区别在于:

  • django-cron 完全运行在 django 服务器内部的库,它通过定期检查当前时间与定义的任务计划是否匹配来执行任务。它不依赖于系统级的cron守护进程,而是基于 django 自身的请求周期触发任务检查
  • django-crontab 是利用操作系统的 cron 守护进程来调度任务。用户在 django 项目中定义好任务后, django-crontab 会将这些任务写入到系统的 crontab 文件中。当 cron 守护进程执行任务时,实际上会调用 django 管理命令或 url 来执行特定的操作。

django-crontab

使用 django-crontab 需要以下步骤:

  1. 安装 django-crontab 模块
  2. settings.py 中注册应用
  3. 创建定时执行的任务(可以是自定义的函数或自定义的命令)
  4. settings.py 中配置执行任务
  5. 执行任务

需要注意的是 django-crontab 只能运行在 linux 环境中,且需要使用到 root 权限。另外需要启动 cron 服务

# 查看 cron 服务状态
service cron status
# 开启 cron 服务
service cron start
# 查看定时任务
crontab -l
# 添加定时任务 
crontab -e

安装 django-crontab

pip install django-crontab

注册应用

settings.py 中注册 django-crontab 应用

INSTALLED_APPS = [
		...
    'django_crontab',
]

创建任务

创建定时执行的任务

创建定时执行函数

在任意 app 下均可创建定时执行函数

# app1/task.py

def scheduleTask():		# 定时执行函数
    from time import strftime, localtime
    print(strftime("%Y-%m-%d %H:%M:%S", localtime()), end='')
    print("执行了scheduleTask函数")

def scheduleTaskWithPara(in_str):		# 带参数的定时执行函数
	import datetime
	now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
	print(f"在 {now_time} 执行了定时函数,输入信息{in_str}")
创建定时执行命令

在任意 app 下创建 management 模块(含有 __init__.py 文件),并在此模块下创建 commands 模块。在 commands 模块下创建具体的执行脚本文件。例如:

# app1/management/commands/mycommand1.py

from django.core.management.base import BaseCommand, CommandError
from time import strftime, localtime
	
class Command(BaseCommand):
    help = '这是第一个command测试指令'

    # 为handle中添加参数解析,
    def add_arguments(self, parser):
        parser.add_argument(
            '-p', # 设置参数的时候  前边携带
            '--param',
            action='store',
            dest='param',  # 自定义传入的参数键名ss
            default='close',  # 默认的键值
            help='name of author.',
        )

    def handle(self, *args, **options):
        # print("mycommand1----开始")
        '''
        添加你需要功能,(访问数据库,判断有效性等等)...
        '''
        # 例如
        try:
            if options['param']:
                print(strftime("%Y-%m-%d %H:%M:%S", localtime()), end='')
                print(": mycommand1传入的参数为", options['param'])
        except Exception as e:
            print("12",e)
            print(CommandError("1111111111111111111111111"))
        # print("mycommand1----结束")
# app1/management/commands/mycommand2.py

from django.core.management.base import BaseCommand
from time import strftime, localtime

class Command(BaseCommand):
    help = '这是第二个command测试指令'

    # 为handle中添加参数解析,
    def add_arguments(self, parser):
        parser.add_argument(
            '-p', # 设置参数的时候  前边携带
            '--param',
            action='store',
            dest='param',  # 自定义传入的参数键名ss
            default='close',  # 默认的键值
            help='name of author.',
        )

    def handle(self, *args, **options):
        # print("mycommand2----开始")
        '''
        添加你需要功能,(访问数据库,判断有效性等等)...
        '''
        # 例如
        if options['param']:
            print(strftime("%Y-%m-%d %H:%M:%S", localtime()), end='')
            print("mycommand2传入的参数为", options['param'])
        # print("mycommand2----结束")

配置任务

将创建好的定时执行任务配置到 settings.py 中去,以方便执行

配置定时执行函数

在 CRONJOBS 列表中添加一个元组,第一个元素是执行间隔时间,第二个元素是执行任务函数。如没有参数第三个元素是输出处理,如有参数第三、四元素分别为传参,第五参数是输出处理。例如:

CRONJOBS = [
    # 每1分钟执行scheduleTask函数,并将执行中的返回的内容全部打印到crontab.log文件中
    ('*/1 * * * *', 'app1.tasks.scheduleTask', '>> /tmp/crontab.log'),
    ('*/1 * * * *', 'app1.tasks.scheduleTaskWithPara', ['James'], {}, '>> /tmp/crontab.log'),
]
配置定时执行命令

类似于定时执行函数,将定时执行命令添加到 CRONJOBS 列表中去。区别在于元组的元素定义不同

CRONJOBS = [
    # 每1分钟执行django的自定义命令,并将执行中的返回的内容全部打印到crontab.log文件中
    ('*/1 * * * *', 'django.core.management.call_command', ['mycommand1'], {"param": "mycommand1_test"}, '>>/home/wangzhipeng/myproject/crontab.log'),
    ('*/1 * * * *', 'django.core.management.call_command', ['mycommand2'], {"param": "mycommand2_test"}, '>>/home/wangzhipeng/myproject/crontab.log')
]
  • 元素1:定时 例如*/1 * * * * 表示每隔1分钟执行
  • 元素2:方法的python模块路径,如果执行django-admin命令,则写django.core.management.call_command
  • 元素3:方法的位置参数列表(默认值:[]),如果执行django-admin命令,则填写所需执行的命令
  • 元素4:方法的关键字参数的dict(默认值:{})
  • 元素5:执行log存放位置(即重定向到文件,默认:‘’)

配置完成后可以进行测试:

python manage.py mycommand1 -p 123
# 2019-05-10 15:10:59: mycommand1传入的参数为 123
关于 linux 的 crontab 时间语法

crontab 的时间语法由五部分组成,通常为五个 *,每一位表示的意思分别为:分钟、小时、日、月、星期。
可使用的字符和其意义为:

字符 含义
* 代表所有取值范围的数字
/ 代表“每”的意思,例如 */5 表示5个单位
- 代表从某个数字到某个数字
, 分隔离散的数字

例如:

示例 含义
0 */2 * * * 每2个小时
0 23-7,9 * * * 23点到7点,或9点
0 11 4 * 1-3 每月4号或周一到三的11点
0 4 1 1 * 1月1日4点
0 6 * * * 每天6点
0 */2 * * * 每2小时

执行任务

添加并开启定时任务:

python manage.py crontab add

查看执行中的定时任务

python manage.py crontab show

删除(停止)定时任务

python manage.py crontab remove 

django-cron

django-cron 因为完全基于 django,使得使用简单。但是也是这个原因,要想使定时任务生效,django服务必须一直处于运行状态。

另外 django-cron django-cron会依赖于HTTP请求来触发其内部的任务检查逻辑(通过中间件实现)。这意味着只有当有用户访问网站或通过其他方式触发HTTP请求时,cron任务才可能被执行。

需注意的是,dnango-cron 也只能在 linux 系统上运行。

(django-cron英文文档)[https://django-cron.readthedocs.io/en/latest/]

使用 django-cron 需要以下步骤:

  1. 安装 django-cron 模块
  2. settings.py 中注册应用
  3. 进行迁移,创建 django_cron 应用所需资源
  4. 创建定时执行的任务类
  5. settings.py 中配置执行任务

安装 django-cron

pip install django-cron

注册应用

settings.py 中注册应用:

INSTALLED_APPS = [
    # ...
    "django_cron",
]

创建 django_cron 资源

python manage.py migrate django_cron

创建任务类

和 django-crontab 不同的是, django-cron 的定时任务是一个集成自 django_cron.CronJobBase 的类

# app1/cron.py
from django_cron import CronJobBase, Schedule
from django.core.management import call_command

class MyCronJob(CronJobBase):
    RUN_EVERY_MINS = 30  # 每30分钟运行一次
    schedule = Schedule(run_every_mins=RUN_EVERY_MINS)		# 添加任务执行周期
    code = 'yourapp.my_cron_job'  # 唯一标识符

    def do(self):
        # 执行的命令或函数
        call_command('your_management_command')  # 如果是管理命令
        # 或执行任意Python代码
        my_function()

如果需要在指定时间执行任务,而不是按周期执行,则使用schedule = Schedule(run_at_times=['11:30', '14:00', '23:15']),注意必须使用24小时制。按照周期执行和执行时间执行可以一起使用。schedule = Schedule(run_every_mins=RUN_EVERY_MINS, run_at_times=RUN_AT_TIMES)

配置任务

需要在 settings.py 中的 CRON_CLASSES 列表中注册此任务

CRON_CLASSES = [
    "app1.cron.MyCronJob",
]

执行任务

在 django-cron 中,定时任务是在 django 应用运行时触发执行的。如果需要立即运行所有的 cron 任务,例如部署新代码后或进行测试时,可以手动执行任务。

python manage.py runcrons

也可以单独指定手动执行具体的哪个任务类

python manage.py runcrons "app1.cron.MyCronJob" "app1.cron.OtherCronJob"

如果需要静默执行,即不输出相关信息,可以添加参数 --silent
如果需要强制执行,可以添加参数 --force
如果需要查看有哪些任务可以执行,而并不真的运行这些任务,可以添加参数 --dry-run

django-apscheduler

cron 是基于 unix_like 系统的,windows 下使用 APScheduler。APscheduler全称Advanced Python Scheduler,它是一个轻量级的 Python 定时任务调度框架。APScheduler 支持三种调度任务:固定时间间隔,固定时间点(日期),Linux 下的 Crontab 命令。同时,它还支持异步执行、后台执行调度任务。

django-apscheduler 是 APScheduler 的django定制封装插件版,专为 django 设计。它的使用流程为:

  1. 安装
  2. 注册应用
  3. 配置
  4. 执行迁移
  5. 创建任务
  6. 初始化调度器,启动任务

apscheduler英文文档

安装

pip install django-apscheduler

你可能感兴趣的:(python,django,python,django)