项目的public文件夹下创建job.py文件
具体完成定时任务的创建、运行、暂停、删除操作
from public.log import *
from tasks import sched
from public.utils import import_method,task_time
class Job(object):
def __init__(self,task_name):
self.task_name = task_name
# 添加定时任务并启动
def add_cron_task(self,func,schedule):
flag = 1
try:
func = import_method(func)
job = func
schedule = task_time(schedule)
secends = schedule[0]
minutes = schedule[1]
hours = schedule[2]
month = schedule[3]
dayofweek = schedule[4]
sched.add_job(job, 'cron',second=secends,minute=minutes,hour=hours,day_of_week=dayofweek,month=month, id = self.task_name)
writeLog_info('[定时任务:%s],添加成功' % (self.task_name))
flag = 0
except Exception as e:
writeLog_error('[定时任务:%s],添加失败:%s' % (self.task_name, str(e)))
return flag
# 暂停任务
def pause_cron_task(self):
flag = 1
try:
sched.pause_job(self.task_name)
writeLog_info('[定时任务:%s],暂停成功' % (self.task_name))
flag = 0
except Exception as e:
writeLog_error('[定时任务:%s],暂停失败:%s' % (self.task_name, str(e)))
return flag
# 恢复任务
def resume_cron_task(self):
flag = 1
try:
sched.resume_job(self.task_name)
writeLog_info('[定时任务:%s],重启成功' % (self.task_name))
flag = 0
except Exception as e:
writeLog_error('[定时任务:%s],重启失败:%s' % (self.task_name, str(e)))
return flag
# 移除任务
def remove_cron_task(self):
flag = 1
try:
sched.remove_job(self.task_name)
writeLog_info('[定时任务:%s],删除成功' % (self.task_name))
flag = 0
except Exception as e:
writeLog_error('[定时任务:%s],删除失败:%s' % (self.task_name, str(e)))
return flag
#判断当前是否有运行中的定时任务
def is_exsit_task():
flag = 1
try:
tasks = sched.get_jobs()
if tasks:
flag = 0
writeLog_info('当前运行中的定时任务:%s' % (tasks))
else:
flag = 1
writeLog_info('暂无运行中的定时任务,需要手动开启')
except Exception as e:
writeLog_error('定时任务获取失败:%s'%(str(e)))
return flag
这里在public/utils中写了两个数据处理方法import_method,task_time
#定时任务函数引用处理
def import_method(resource):
resource = resource.split('.')
moduel_name = resource[0]
class_name = resource[1]
method_name = resource[2]
moduel =importlib.import_module(moduel_name+'.'+class_name)
c = getattr(moduel,class_name)
method = getattr(c(),method_name)
return method
#定时任务执行时间处理
def task_time(time):
time_list = time.strip(',').split(',')
return time_list
项目下新建tasks APP
models.py中将任务写入数据库
from django.db import models
# Create your models here.
class Task(models.Model):
task_name = models.CharField(max_length=32,verbose_name=u'任务名称',default="",primary_key=True)
task_method = models.CharField(max_length=20,verbose_name=u'调用方法',default="")
task_des = models.CharField(max_length=200,verbose_name=u'任务描述',default="")
task_schedule = models.CharField(max_length=20,verbose_name=u'执行计划',default="")
status = models.IntegerField(choices = ((0,u'运行中'),(1,u'未开启')),default=0, verbose_name=u'项目状态')
update_time = models.DateTimeField(auto_now=True, verbose_name=u'更新时间')
create_time = models.DateTimeField(auto_now_add=True, verbose_name=u'创建时间')
class Meta:
verbose_name =u'定时任务'
verbose_name_plural = verbose_name
def __str__(self):
return self.task_name
tasks APP的init.py文件
default_app_config = 'tasks.apps.TasksConfig'
from apscheduler.schedulers.background import BackgroundScheduler
sched=BackgroundScheduler()
sched.start()
tasks APP的taskviews.py文件
# _*_ encoding:utf-8 _*_
from django.shortcuts import redirect, reverse
from django.shortcuts import HttpResponse
from public.job import *
import json
from .models import Task
from public.utils import *
# 定时任务列表
@login_Check
def task(request):
try:
is_exsit_task()
tasks = Task.objects.all()
writeLog_info("定时任务列表:%s" % tasks)
return render(request, "../templates/tasks/task.html", {'tasks': tasks})
except Exception as e:
writeLog_info("定时任务列表获取失败:%s" % str(e))
# 定时任务创建
@login_Check
def add_task(request):
if request.method == 'POST':
task_name = request.POST.get("task_name")
task_method = request.POST.get("task_method")
task_des = request.POST.get("task_des")
task_schedule = request.POST.get("task_schedule")
isRepeat = len(Task.objects.filter(task_name=task_name).values())
# 不重复则新增数据
if isRepeat == 0:
try:
job = Job(task_name)
if (job.add_cron_task(task_method, task_schedule)) == 0:
Task.objects.create(task_name=task_name, task_method=task_method, task_des=task_des,
task_schedule=task_schedule)
writeLog_info(u"定时任务[%s],创建成功" % (task_name))
except Exception as e:
writeLog_error(u"定时任务创建失败" % (str(e)))
tasks = Task.objects.all()
return render(request, "../templates/tasks/task.html", {'tasks': tasks,'isRepeat':isRepeat})
# 修改:任务回显
@login_Check
def show_task(request):
if request.method == 'POST':
task_name = request.POST.get("task_name")
task_obj = Task.objects.get(task_name=task_name)
task_method = task_obj.task_method
task_des = task_obj.task_des
task_schedule = task_obj.task_schedule
return HttpResponse(json.dumps({
"task_name":task_name,
"task_method": task_method,
"task_des": task_des,
"task_schedule": task_schedule,
}))
return redirect(reverse(task))
# 定时任务修改
@login_Check
def modify_task(request):
if request.method == 'POST':
task_name = request.POST.get("task_name")
task_method = request.POST.get("task_method")
task_des = request.POST.get("task_des")
task_schedule = request.POST.get("task_schedule")
status = 0
try:
job = Job(task_name)
if (job.remove_cron_task()) == 0:
Task.objects.filter(task_name=task_name).delete()
if (job.add_cron_task(task_method, task_schedule)) == 0:
Task.objects.filter(task_name=task_name).update(task_method=task_method, task_des=task_des,
task_schedule=task_schedule,status=status)
writeLog_info(u"定时任务[%s],更新成功" % (task_name))
else:
writeLog_error(u"定时任务[%s],更新失败" % (task_name))
else:
if (job.add_cron_task(task_method, task_schedule)) == 0:
Task.objects.filter(task_name=task_name).update(task_method=task_method, task_des=task_des,
task_schedule=task_schedule,status=status)
writeLog_info(u"定时任务[%s],更新成功" % (task_name))
else:
writeLog_error(u"定时任务[%s],更新失败" % (task_name))
except Exception as e:
writeLog_error(u"定时任务[%s],更新失败:%s" % (task_name,str(e)))
return redirect(reverse(task))
# 定时任务暂停
@login_Check
def pause_task(request):
if request.method == 'POST':
task_name = request.POST.get("task_name")
try:
job = Job(task_name)
if (job.pause_cron_task()) == 0:
Task.objects.filter(task_name=task_name).update(status=1)
writeLog_info(u"定时任务[%s],暂停成功" % (task_name))
else:
Task.objects.filter(task_name=task_name).update(status=1)
writeLog_info(u"定时任务[%s],暂停成功" % (task_name))
return redirect(reverse(task))
except Exception as e:
writeLog_error(u"定时任务暂停失败" % (str(e)))
return redirect(reverse(task))
# 定时任务重启
@login_Check
def restart_task(request):
if request.method == 'POST':
task_name = request.POST.get("task_name")
try:
job = Job(task_name)
if (job.resume_cron_task()) == 0:
Task.objects.filter(task_name=task_name).update(status=0)
writeLog_info(u"定时任务[%s],重启成功" % (task_name))
else:
obj = Task.objects.get(task_name=task_name)
task_method = obj.task_method
task_schedule = obj.task_schedule
job.add_cron_task(task_method, task_schedule)
Task.objects.filter(task_name=task_name).update(status = 0)
writeLog_info(u"定时任务[%s],重启成功" % (task_name))
return redirect(reverse(task))
except Exception as e:
writeLog_error(u"定时任务重启失败" % (str(e)))
return redirect(reverse(task))
# 定时任务删除
@login_Check
def remove_task(request):
if request.method == 'POST':
task_name = request.POST.get("task_name")
try:
job = Job(task_name)
if (job.remove_cron_task()) == 0:
Task.objects.filter(task_name=task_name).delete()
else:
Task.objects.filter(task_name=task_name).delete()
writeLog_info(u"定时任务[%s],删除成功" % (task_name))
except Exception as e:
writeLog_error(u"定时任务删除失败" % (str(e)))
return redirect(reverse(task))
tasks APP下的utls.py文件中添加路由分发
# _*_ coding:utf-8 _*_
__author__ = 'jessy'
__date__ = '2018/12/18 14:48'
from django.conf.urls import url
from . import taskviews
urlpatterns = [
url('^taskinfo/$', taskviews.task),
url('^taskinfo/add_task/$', taskviews.add_task),
url('^taskinfo/show_task/$', taskviews.show_task),
url('^taskinfo/modify_task/$', taskviews.modify_task),
url('^taskinfo/pause_task/$', taskviews.pause_task),
url('^taskinfo/restart_task/$', taskviews.restart_task),
url('^taskinfo/remove_task/$', taskviews.remove_task),
]
templates/task文件夹下添加task.html文件
<!DOCTYPE html>
<html lang="en">
<head>
{% load bootstrap3 %}
<title>Tasks</title>
<script src="/static/bootstrap/js/jquery.min.js"></script>
<script src="/static/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
<link rel="stylesheet" href="/static/frame/layui/css/layui.css">
<link rel="stylesheet" href="/static/frame/static/css/style.css">
<script>
$(function () {
funisRepeat();
});
function funisRepeat() {
var isRepeat;
isRepeat = "{{ isRepeat }}";
if (isRepeat == 1) {
alert("任务名称重复!");
}
}
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
function csrfSafeMethod(method) {
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
//定时任务暂停
function pauseTask(task_name) {
//alert(id);
if (!confirm("确认要暂停:" + task_name + " 吗?")) {
return
}
$.ajax({
url: '/task/taskinfo/pause_task/',
type: 'POST',
data: {'task_name': task_name},
beforeSend: function (xhr, settings) {
var csrftoken = getCookie('csrftoken');
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
},
success: function (arg) {
alert("暂停成功!")
window.location.reload();
}
})
}
//定时任务重启
function restartTask(task_name) {
//alert(id);
if (!confirm("确认要重启:" + task_name + " 吗?")) {
return
}
$.ajax({
url: '/task/taskinfo/restart_task/',
type: 'POST',
data: {'task_name': task_name},
beforeSend: function (xhr, settings) {
var csrftoken = getCookie('csrftoken');
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
},
success: function (arg) {
alert("重启成功!")
window.location.reload();
}
})
}
// 用户信息回显
function showTask(task_name) {
//alert(task_name);
$.ajax({
url: '/task/taskinfo/show_task/',
type: 'POST',
data: {'task_name': task_name},
beforeSend: function (xhr, settings) {
var csrftoken = getCookie('csrftoken');
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
},
success: function (data) {
//alert(data);
var parseJson = jQuery.parseJSON(data)
$("#task_name_show").val(parseJson.task_name);
$("#task_method_show").val(parseJson.task_method);
$("#task_des_show").val(parseJson.task_des);
$('#task_schedule_show').val(parseJson.task_schedule);
$('#task_editMyModal').modal("show");
},
})
}
// 定时任务删除
function removeTask(task_name) {
//alert(id);
if (!confirm("确认要删除:" + task_name + " 吗?")) {
return
}
$.ajax({
url: '/task/taskinfo/remove_task/',
type: 'POST',
data: {'task_name': task_name},
beforeSend: function (xhr, settings) {
var csrftoken = getCookie('csrftoken');
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
},
success: function (arg) {
alert("删除成功!")
window.location.reload();
}
})
}
</script>
</head>
<body role="document">
<!--定时任务列表-->
<div style="padding-top:20px;">
<div class="layui-row layui-col-space15">
<div class="layui-col-md10">
<!--按钮-->
<div class="btn-group">
<button id="btn1" class="layui-btn btn " data-toggle="modal" data-target="#task_addMyModal">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>定时任务
</button>
</div>
<!--用户列表-->
<div style="padding-top:10px">
<div>
<table id="table" table class="layui-table" lay-skin="line">
<thead>
<tr>
<th hidden>任务id</th>
<th>任务名称</th>
<th>方法</th>
<th>描述</th>
<th>执行计划</th>
<th>状态</th>
<th> 操作</th>
</tr>
</thead>
<tbody>
{% for task in tasks %}
<tr>
<td class="list" hidden>{{ task.id }}</td>
<td class="list" width="180">{{ task.task_name }}</td>
<td class="list" width="180">{{ task.task_method }}</td>
<td class="list" width="180">{{ task.task_des }}</td>
<td class="list" width="180">{{ task.task_schedule }}</td>
<td class="list" width="180">
{% if task.status == 1 %}
<a style="color:red">{{ task.get_status_display }}</a>
{% else %}
<a style="color:yellowgreen">{{ task.get_status_display }}</a>
{% endif %}
</td>
<td class="list" width="250">
{% if task.status == 1 %}
<a id="task_start" href="javascript:void(0)"
onclick="restartTask('{{ task.task_name }}')">
<img src="/static/admin/img/icon-yes.svg">重启</a>
<a id="task_modify" href="javascript:void(0)"
onclick="showTask('{{ task.task_name }}')">
<img src="/static/admin/img/icon-changelink.svg">修改</a>
<a href="javascript:void(0)"
onclick="removeTask('{{ task.task_name }}')">
<img src="/static/admin/img/icon-deletelink.svg">删除
</a>
{% else %}
<a id="task_pause" href="javascript:void(0)"
onclick="pauseTask('{{ task.task_name }}')">
<img src="/static/admin/img/icon-alert.svg">暂停</a>
<a href="javascript:void(0)"
onclick="removeTask('{{ task.task_name }}')">
<img src="/static/admin/img/icon-deletelink.svg">删除
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- 模态框示例(Modal) -->
<!-- 新增定时任务-->
<div class="modal fade" id="task_addMyModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"
aria-hidden="true">
<div class="modal-dialog" style="max-width:800px">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">
×
</button>
<h3 class="modal-title" id="myModalLabel">
<p style="font-size: medium">新增定时任务</p>
</h3>
</div>
<div class="modal-body">
<form id='addMenu' role="form" method='POST' action="/task/taskinfo/add_task/">
<div class="form-group">
<label for="task_name">任务名称</label>
<input type="text" class="form-control" name="task_name" placeholder="请输入任务名称" required
maxlength="32">
</div>
<div class="form-group">
<label for="task_method">调用方法</label>
<input type="text" class="form-control" name="task_method" placeholder="请输入调用方法" required
maxlength="20">
</div>
<div class="form-group">
<label for="task_des">描述</label>
<input type="text" class="form-control" name="task_des" placeholder="请输入描述信息" required
maxlength="200">
</div>
<div class="form-group">
<label for="task_schedule">执行计划(秒,分,小时,月,天/周)</label>
<input type="text" class="form-control" name="task_schedule"
placeholder="请输入执行计划(例:*/10,*,*,*,*)" maxlength="20">
</div>
<div class="modal-footer">
<button type="button" class="btn layui-btn" data-dismiss="modal">关闭
</button>
<button type="submit" class="btn layui-btn">
提交
</button>
</div>
{% csrf_token %}
</form>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal -->
</div>
<!-- 修改定时任务-->
<div class="modal fade" id="task_editMyModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"
aria-hidden="true">
<div class="modal-dialog" style="max-width:800px">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">
×
</button>
<h3 class="modal-title" id="myModalLabel">
<p style="font-size: medium">定时任务修改</p>
</h3>
</div>
<div class="modal-body">
<form id='modifyMenu' role="form" method='POST' action="/task/taskinfo/modify_task/">
<div class="form-group" style="display: none">
<label for="id">id</label>
<input id="user_id" type="text" class=" form-control" name="id" placeholder="请输入id">
</div>
<div class="form-group">
<label for="task_name">任务名称</label>
<input id="task_name_show" type="text" class="form-control" name="task_name" required
maxlength="32" readonly="readonly">
</div>
<div class="form-group">
<label for="task_method">调用方法</label>
<input id="task_method_show" type="text" class="form-control" name="task_method"
placeholder="请输入调用方法" required maxlength="20">
</div>
<div class="form-group">
<label for="task_des">描述</label>
<input id="task_des_show" type="text" class="form-control" name="task_des" placeholder="请输入描述信息"
required maxlength="200">
</div>
<div class="form-group">
<label for="task_schedule">执行计划(秒,分,小时,月,天/周)</label>
<input id="task_schedule_show" type="text" class="form-control" name="task_schedule"
placeholder="请输入执行计划(例:*/10,*,*,*,*)" maxlength="20">
</div>
<div class="modal-footer">
<button type="button" class="btn layui-btn" data-dismiss="modal">关闭
</button>
<button type="submit" class="btn layui-btn">
提交
</button>
</div>
{% csrf_token %}
</form>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal -->
</div>
</body>
</html>
image.png
网友评论