详解django-apscheduler的使用方法-程序员宅基地

技术标签: Python  

转载:详解django-apscheduler的使用方法

如果你在使用Django框架开发web项目时,需要设置定时任务或让用户手动在页面上设置定时任务,那么这篇文章可能会帮助到你。

概述

在Django中实现定时任务功能大概有以下三种方法:

Celery框架

定时任务是分布式任务的一种特殊类型的任务。Django的分布式主要由Celery框架实现,这是python开发的分布式任务队列。由于它本身不支持消息存储服务,所以需要第三方消息服务来传递任务,一般使用Redis。

优点:

  1. Celery侧重于实时操作,可用于生产系统每天处理数以百万计的任务,可用于大型项目。
  2. 可在分布的机器、进程、线程上执行任务调度。

缺点:

配置和使用较为复杂,需要Redis数据库和多个python第三方库。

django-crontab

只需要下载一个 django-crontab 包就可以使用cron表达式在Django框架中设置定时任务。本人对这种方法了解不多,不过这种方法好像不支持windows系统,功能也相对简单。

django-apscheduler

配置简单、功能齐全、使用灵活、支持windows和linux,适合中小型项目。

使用方法

django-apscheduler中相关的概念和python的定时任务框架apscheduler中的概念是一样的,有感兴趣的同学可以自行查阅。

(本文使用 django + mysql 架构)

安装模块

pip install django-apscheduler

配置

  1. 先在settings.py中配置好数据库信息(略).
  2. INSTALLED_APPS中加入django-apscheduler应用:
    INSTALLED_APPS = [
        ...
        'django_apscheduler',
        ...
    ]

执行迁移

python manage.py migrate

去数据库中看一看,生成了两个表格,大部分都顾名思义。

1. django_apscheduler_djangojob

用于存储任务的表格

img

job_state: 我猜是将任务具体的执行代码和参数进行序列化后存在了这里

2. django_apscheduler_djangojobexecution

用于存储任务执行状态的表格

img

status: 执行状态
duration: 执行了多长时间
exception: 是否出现了什么异常

使用

创建任务

大概有两种创建任务的方法:装饰器和add_job函数。

1. 装饰器

在任意view.py中实现代码(我习惯新开一个app专门实现定时任务):

from apscheduler.schedulers.background import BackgroundScheduler
from django_apscheduler.jobstores import DjangoJobStore, register_events, register_job

# 实例化调度器
scheduler = BackgroundScheduler()
# 调度器使用默认的DjangoJobStore()
scheduler.add_jobstore(DjangoJobStore(), 'default')

# 每天8点半执行这个任务
@register_job(scheduler, 'cron', id='test', hour=8, minute=30,args=['test'])
def test(s):
    # 具体要执行的代码
    pass

# 注册定时任务并开始
register_events(scheduler)
scheduler.start()
复制代码

启动服务 python manage.py runserver 这个任务就会被存储到django_apscheduler_djangojob表中,并按照设置定时的执行程序。

参数
  • scheduler: 指定调度器
  • trigger: 任务执行的方式,共有三种: ‘date’、‘interval’、‘cron’。
    • ‘date’ + ‘run_date’ 的参数组合, 能实现单次任务
      例子: 2019-07-07 22:49:00 执行任务
      @register_job(scheduler, 'date', id='test', run_date='2019-07-07 22:49:00')
      注:在亲测时,执行完任务会报错,原因时执行完任务后会去mysql中删除djangojob表中的任务。但是djangojobexecution表记录着执行结果,有外键关联着djangojob表,所以删除时显示有外键约束错误。但是任务会正常执行,执行之后也会正常删除。
    • ‘interval’ + ‘hours’ + ‘minutes’ + … 的参数组合,能实现间隔性任务
      例子:每隔3个半小时执行任务
      @register_job(scheduler, 'interval', id='test', hours=3, minutes=30)
      还有seconds,days参数可以选择
      注:如果任务需要执行10秒,而间隔设置为1秒,它是不会给你开10个线程同时去执行10个任务的。它会错过其他任务直到当前任务完成。
    • ‘cron’ + ‘hour’ + ‘minute’+…的参数组合,能实现cron类的任务
      例子:每天的8点半执行任务
      @register_job(scheduler, 'cron', id='test', hour=8, minute=30)
      还有day,second,month等参数可以选择。
  • id: 任务的名字,不传的话会自动生成。不过为了之后对任务进行暂停、开启、删除等操作,建议给一个名字。并且是唯一的,如果多个任务取一个名字,之前的任务就会被覆盖。
  • args: list类型。执行代码所需要的参数。
  • next_run_time:datetime类型。开始执行时间。如果你现在创建一个定时任务,想3天后凌晨三点半自动给你女朋友发微信,那就需要这个参数了。

还有些其他的参数感兴趣的同学可以查看源代码来了解。

2. add_job函数

装饰器的方法适合于写代码的人自己创建任务,如果想让用户通过页面输入参数,并提交来手动创建定时任务,就需要使用add_job函数。
下面这个小例子,前端传递json数据给后端,触发test_add_task函数,来添加任务:

import json
from django.http import JsonResponse
from apscheduler.schedulers.background import BackgroundScheduler
from django_apscheduler.jobstores import DjangoJobStore, register_events, register_job


scheduler = BackgroundScheduler()
scheduler.add_jobstore(DjangoJobStore(), 'default')

# 与前端的接口
def test_add_task(request):
    if request.method == 'POST':
        content = json.loads(request.body.decode())  # 接收参数
        try:
            start_time = content['start_time']  # 用户输入的任务开始时间, '10:00:00'
            start_time = start_time.split(':')
            hour = int(start_time)[0]
            minute = int(start_time)[1]
            second = int(start_time)[2]
            s = content['s']  # 接收执行任务的各种参数
            # 创建任务
            scheduler.add_job(test, 'cron', hour=hour, minute=minute, second=second, args=[s])
            code = '200'
            message = 'success'
        except Exception as e:
            code = '400'
            message = e
            
        back = {
            'code': code,
            'message': message
        }
        return JsonResponse(json.dumps(data, ensure_ascii=False), safe=False)
        
# 具体要执行的代码
def test(s):
    pass
    

register_events(scheduler)
scheduler.start()
复制代码

这样就可以由前端用户来手动设置定时任务了。

参数

和装饰器的参数大同小异,只是第一个参数不同。
如果具体要执行的函数和调用它的函数在一个文件中,那么只需要传递这个函数名就可以了(如上面的例子)。
但是我习惯将具体的业务代码写到另外一个文件中,view.py中只写前后端交互的接口函数,这种情况下传递的参数为一个字符串,格式为: ‘package.module:some.object’,即 包名.模块:函数名

其他功能

django-apscheduler框架还提供了很多操作定时任务的函数。比如:

  • 删除任务
    scheduler.remove_job(job_name)
  • 暂停任务
    scheduler.pause_job(job_name)
  • 开启任务
    scheduler.resume_job(job_name)
  • 修改任务
    scheduler.modify_job(job_name)
    注:修改任务只能修改参数,如果要修改执行时间的话,就把任务删了重新创建。

可以在页面上做一个这样的表格,再加上简单的前后端交互就可以让用户自行管理定时任务:

img

其他的还有一些辅助功能(包括显示所有任务,显示任务的执行时间等),同学们可以自行查看。
最后,感谢阅读。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_41524366/article/details/106832708

智能推荐

MAME打开ROM报错解决办法_mame bios and devices sets-程序员宅基地

文章浏览阅读6.1k次。MAME打开ROM红屏报错的解决办法_mame bios and devices sets

什么是CAP理论? cp ap原则的含义-程序员宅基地

文章浏览阅读1.2k次。什么是CAP理论?CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾CAP分别是什么?一致性(Consistency) (所有节点在同一时间具有相同的数据)可用性(Availability) (保证每个请求不管成功或者失败都有响应)分区容错性(Partition tolerance) (系统中任意信息的丢失或_cp ap

Linux Kernel 2.4.x / 2.6.x uselib() Local Privilege Escalation Exploit-程序员宅基地

文章浏览阅读195次。/** pwned.c - linux 2.4 and 2.6 sys_uselib local root exploit. PRIVATE.* it's not the best one, the ldt approach is definitively better.* discovered may 2004. no longer private beca..._linux 2.4 挖洞

C/C++ —— 十六进制类型字符串的转换_c++ 16进制转字符串-程序员宅基地

文章浏览阅读9.5k次,点赞2次,收藏4次。在实际工作中,字符串和其它数据类型的转换是很常见的,库函数有很多,比如 atoi , strtol , sscanf 等,这些函数网上有很多资料,我经常用到的就是十六进制的数值以字符串的形式传输,然后又要解析,这里记录一下我这边的做法:将2个字节的十六进制的字符串转成short int 2个字节的整形数据:_c++ 16进制转字符串

Kafka实战:从RDBMS到Hadoop,七步实现实时传输-程序员宅基地

文章浏览阅读4.8k次。对于那些想要把数据快速摄取到Hadoop中的企业来讲,Kafka是一个很好的选择。Kafka是什么?Kafka是一个分布式、可伸缩、可信赖的消息传递系统,利用发布-订阅模型来集成应用程序/数据流。同时,Kafka还是Hadoop技术堆栈中的关键组件,能够很好地支持实时数据分析或者货币化的物联网数据。

SharedPreferencesUtils_sharedpreferencesutils 爆红-程序员宅基地

文章浏览阅读216次。package com.goodfamily.gps.polling_and_maintenance.util;import java.util.Set;import android.annotation.SuppressLint;import android.app.Activity;import android.content.Context;import andr_sharedpreferencesutils 爆红

随便推点

spring开启注解的三种方式-程序员宅基地

文章浏览阅读1.2w次。本章使用c3p0做演示 方法一,编辑试事务开启事务核心类 DataSourceTransactionManager,不管是哪一种方式都需要创建该对象,该方式需要记住的类 TransactionTemplate, 其实很好记,使用spring操作数据库创建jdbcTemplate ,使用spring开启事务创建TransactionTemplatepublic class Transact_spring开启注解的三种方式

这份字节跳动历年校招Java面试真题解析,年薪50W_前端校招面试真题解析大全-程序员宅基地

文章浏览阅读174次。写在前面很多小伙伴留言说让我写一些工作过程中的真实案例,写些啥呢?想来想去,写一篇我在以前公司从零开始到用户超千万的数据库架构升级演变的过程吧。本文记录了我之前初到一家创业公司,从零开始到用户超千万,系统压力暴增的情况下是如何一步步优化MySQL数据库的,以及数据库架构升级的演变过程。升级的过程极具技术挑战性,也从中收获不少。希望能够为小伙伴们带来实质性的帮助。这些面试题你都会了吗?(精选97道Java核心面试题)常量池有哪些,数据结构,自己设计一个常量池String为啥设计为final,好_前端校招面试真题解析大全

mac系统下配置tomcat_tomcat苹果与windows有区别吗-程序员宅基地

文章浏览阅读380次。mac tomcat的安装_tomcat苹果与windows有区别吗

前端必会:CDN加速原理-程序员宅基地

文章浏览阅读137次。作者:Kandyhttps://www.jianshu.com/p/1dae6e1680ff一、什么是 CDNCDN的全称是(Content Delivery Network),即内..._前端面试 cdn加速原理,没有缓存到哪里拿

小习惯-程序员宅基地

文章浏览阅读334次。生活在熙熙攘攘中从未变得安静,有时候感觉自己就像一辆行走着的汽车,向往着速度,应和着节奏。

ABSTRACT SQL CONFIGURE 代码分析一_abstractsql sql.or()-程序员宅基地

文章浏览阅读500次。2021SC@SCSDU对于SQL的配置public abstract class AbstractSQLConfig implements SQLConfig { private static final String TAG = "AbstractSQLConfig"; public static String DEFAULT_DATABASE = DATABASE_MYSQL; public static String DEFAULT_SCHEMA = "sys";..._abstractsql sql.or()