在django中使用apscheduler 执行计划任务的实现方法


Posted in Python onFebruary 11, 2020

对于任何软件开发人员而言,为将来计划任务都是必不可少的工具。 尽管我们创建的许多编程旨在响应明确的触发或用户事件,但定期执行的后台进程也同样重要。

“每个星期一早晨更新结果。”

“每天晚上分批下单。”

甚至具有每日请求限制的第三方API也隐式要求这种行为。

“我们只能每五分钟请求一次更新。”

幸运的是,许多聪明的人已经解决了这个问题,并且不难找到python本地解决方案。 Advanced Python Scheduler(APS)是一个很好的选择,它具有简单,直观的API以及同类产品中的一些最佳文档。

对于此项目,我们将专注于将APS提供的调度技术与您的常规Django应用程序集成:洛杉矶天气应用程序,该应用程序定期轮询第三方天气api以进行模型更新。

目标是比Django教程进行更深入的探索,同时不要在任何方向上陷入困境。

I.安装APS和其他依赖项

在您的项目目录中,创建一个虚拟环境并激活它

virtualenv env
. env/bin/activate

根据本指南安装和配置PostgreSQL。 在此阶段,我们只需要在您的计算机上启动并运行SQL管理器即可。

另外,我发现使用PgAdmin PostgreSQL GUI有帮助。 在您的计算机上进行设置的详细信息可以在这里找到(使用Python3)。

使用pip安装所有必需的软件包(注意,psycopg2适用于PostgreSQL):

pip install apscheduler django psycopg2 requests
II. Build your app
Create a new Django project:

django-admin.py startproject advancedScheduler
cd advancedScheduler
python manage.py startapp weather

在这个新目录(根目录)中,您将看到另一个名为advancedScheduler的文件夹。 这是Django项目目录。

为避免两地同名的混淆,我们仅将“根目录”称为“根目录”。 让下面的图作为我们跳文件夹冒险的路线图。

[ super_project_directory/ ]
|
+----[ env/ ] <-- Virtualenv stuff
|
+----[ advancedScheduler/ ] <-- the Root Directory
 |
 +----[ advancedScheduler/ ] <-- the Django Project Directory
 |
 +----[ weather/ ] <-- the Django App Directory

尽管主要专注于演示调度程序的功能,但让我们花点时间连接Django应用。

我们首先要将天气应用添加到项目的INSTALLED_APPS中。 该文件位于advancedScheduler / settings.py文件中。

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'weather'
]

接下来,将新的网址格式添加到advancedScheduler / urls.py文件中:

path('', include('weather.urls'))

毫不奇怪,我们的下一步将是将该urls.py文件添加到weather app目录中。 将以下代码包含在weather / urls.py中:

from django.conf.urls import url
from weather import views
urlpatterns = [
 url(r'^$', views.MainPage.as_view())
]

在天气应用程序目录中创建一个模板文件夹。 将index.html文件添加到此新文件夹。

以下是我们的MTV。

模型

from django.db import models
from datetime import datetime 
 
class Forecast(models.Model):
 timestamp = models.DateTimeField()
 temperatue = models.DecimalField(max_digits=12,decimal_places=2)
 description = models.CharField(max_length=150)
 city = models.CharField(max_length=150)
 
 def save(self, *args, **kwargs):
 if not self.id:
  self.timestamp = datetime.utcnow()
 return super(Forecast, self).save(*args, **kwargs)
Template
<div style="text-align: center">
 <h5>Currently in</h5>
 <h3>{{city}}</h3>
 <h4>{{temperature_in_f}} F | {{temperature_in_c}} C</h4>
 <h4>{{desctiprion}}</h4>
 <p><em>Last updated {{utc_update_time}} GMT</em></p>
</div>
View
import decimal
from datetime import datetime 
from django.shortcuts import render
from django.views.generic import TemplateView
from weather.models import Forecast 
class MainPage(TemplateView):
 def get(self, request, **kwargs):
 
 latest_forecast = Forecast.objects.latest('timestamp')
 city = latest_forecast.city
 temperature_in_c = latest_forecast.temperatue
 temperature_in_f = (latest_forecast.temperatue * decimal.Decimal(1.8)) + 32
 description = latest_forecast.description.capitalize
 timestamp = "{t.year}/{t.month:02d}/{t.day:02d} - {t.hour:02d}:{t.minute:02d}:{t.second:02d}".format( t=latest_forecast.timestamp)
 return render(
  request, 
  'index.html', 
  {
  'city':city,
  'temperature_in_c': temperature_in_c,
  'temperature_in_f': round(temperature_in_f,2),
  'desctiprion': description,
  'utc_update_time': timestamp})

三, 建立数据库连接并迁移模型

在advancedScheduler / settings.py中,将DATABASES值更改为:

DATABASES = {
 'default': {
 'ENGINE': 'django.db.backends.postgresql_psycopg2',
 'NAME': 'advancedScheduler',
 'USER': 'some_user_name',
 'PASSWORD': 'some_password',
 'HOST': 'localhost',
 'PORT': '',
 }
}

您应该从上述PostgreSQL配置指南(此处和此处)了解USER,PASSWORD和PORT的值。

与PostgreSQL建立连接后,就该迁移我们的模型了。 导航到“根目录”并键入:

python manage.py makemigrations
python manage.py migrate

这样,我们的模型应该已经映射到数据库了。 继续并检查所有内容。 不用担心,我会在这里等你回来。

IV。 预测API

时间到了有趣的部分。 我正在从OpenWeatherMap(一个免费的天气API)中提取我的预报数据,该API将为您授予带有有效电子邮件地址的访问令牌。

现在,由于它在概念上不同于我们的表示层,因此让我们在根目录中创建一个新的ForecastUpdater文件夹。 在其中,我们将添加两个文件:一个空白的__init__.py文件和一个ForecastApi.py文件。 请参阅路线图以供参考。

[ super_project_directory/ ]
|
+----[ env/ ]
|
+----[ advancedScheduler/ ] <-- the Root Directory
 |
 +----[ advancedScheduler/ ] 
 |
 +----[ weather/ ] 
 |
 +----[ forecastUpdater/ ] <-- the new Updater Module
  |
  +----< __init__.py > <--+
  |    |-- two new Python files
  +----< forecastApi.py > <--+
import requests
from weather.models import Forecast
 
def _get_forecast_json():
 url = 'http://api.openweathermap.org/data/2.5/weather'
 encoded_city_name = 'Los%20Angeles'
 country_code = 'us'
 access_token = 'your_access_token'
 
 r = requests.get('{0}?q={1},{2}&APPID={3}'.format(
 url, 
 encoded_city_name, 
 country_code, 
 access_token))
 
 try:
 r.raise_for_status()
 return r.json()
 except:
 return None
 
 
def update_forecast():
 json = _get_forecast_json()
 if json is not None:
 try:
  new_forecast = Forecast()
  
  # open weather map gives temps in Kelvin. We want celsius.  
  temp_in_celsius = json['main']['temp'] - 273.15
  new_forecast.temperatue = temp_in_celsius
  new_forecast.description = json['weather'][0]['description']
  new_forecast.city = json['name']
  new_forecast.save()
  print("saving...\n" + new_forecast)
 except:
  pass

在这里,有一些事情要注意。 异常处理远非健壮。 错误只是被丢弃了—过度的沉默是唯一出问题的迹象。

其次,我们在代码中指定洛杉矶。 将您的服务器配置到所需的任何位置。

同样重要的是要注意,update_forecast()不带任何参数。 我们很快就会看到,我们的高级python计划程序具有严格的无参数规则。 甚至带有孤独的self参数的方法也不会飞。

五,高级Python计划程序

我们已经建立了模型。 我们可以通过调用API来更新数据。 现在我们需要做的就是指定访问该API的频率,这样我们就可以在不超出数据访问限制的情况下提供合理的最新信息。

在ForecastUpdater模块中,添加一个updater.py文件。 在这里,我们将使用Advanced Python Scheduler设置我们的预测更新的节奏。

OpenWeatherMaps使用条款允许在一个小时内保持60个通话,以保持免费等级; 每五分钟更新一次就足够了。

from datetime import datetime
from apscheduler.schedulers.background import BackgroundScheduler
from forecastUpdater import forecastApi
 
def start():
 scheduler = BackgroundScheduler()
 scheduler.add_job(forecastApi.update_forecast, 'interval', minutes=5)
 scheduler.start()

这可能是您可以找到的最简单的APS实现。 如果您查看他们的网站或GitHub上的几个工作示例,则将发现一个完整的功能和设置工具箱,您可以使用这些工具来进行计时,以使其尽可能的细致。

按照我们想要的方式配置了调度程序后,就可以将其连接到Django应用了。

理想情况下,我们希望在调度程序上按一次播放,然后让它执行其任务。 我们需要一种一致且可靠的方式来初始化时间表一次且仅一次。 对于我们而言,Django正是这种类型的运行时初始化逻辑的地方。

在weather / apps.py文件中,您会找到一个名为WeatherConfig的类的存根,该类继承自Django的AppConfig类。

class WeatherConfig(AppConfig):
 name = 'weather'

为了让Django知道它需要在启动时启动更新程序,我们覆盖了AppConfig.ready()方法。

from django.apps import AppConfig
class WeatherConfig(AppConfig):
 name = 'weather'
 def ready(self):
 from forecastUpdater import updater
 updater.start()

重要的是要记住,由于继承的复杂性,此覆盖的任何导入都必须位于ready()方法的主体内。 Django还警告不要在我们的覆盖中直接与数据库进行交互; 生产,调试,风雨无阻,每次启动天气应用程序时,都会执行此代码。

最后,我们现在需要在advancedScheduler / settings.py中再次更新INSTALLED_APPS变量。 Django需要知道我们要使用自定义配置来运行天气应用。

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'weather.apps.WeatherConfig' 
]

VI。 全部放在一起

而已。 在这一点上,我们可以启动我们的应用程序,然后让更新程序执行其操作。

python manage.py runserver --noreload

-noreload标志可防止Django启动天气应用的第二个实例-这是调试模式下的默认行为。 第二个实例意味着我们所有计划的任务将触发两次。

最初,我们的结果看起来不完整。 由于我们将更新程序逻辑安排为每五分钟运行一次,因此我们不停地抽动一下……为了使事情变得有趣,缩短审慎刷新之间的间隔可能是明智的选择,或者在初始化时调用一次update_forecast()。

七。 最后的想法

我们做到了! 我们的天气应用已准备好与世界分享(请在此处查看我的信息)。

Advanced Python Scheduler是任何Python开发人员都知道的好工具。 它在直观的API后面隐藏了非常常见的业务需求的复杂性。 考虑一下,安装程序只用了三行代码。

该项目的真正技巧是与Django框架进行交互-配置,迁移,初始化。 然后,任务自动化成为事后的想法。 五分钟内您就完成了。

https://github.com/kmhoran/la-weather-app

以上所述是小编给大家介绍的在django中使用apscheduler 执行计划任务的实现方法,希望对大家有所帮助!

Python 相关文章推荐
Python面向对象编程中的类和对象学习教程
Mar 30 Python
玩转python爬虫之URLError异常处理
Feb 17 Python
基础的十进制按位运算总结与在Python中的计算示例
Jun 28 Python
简单了解Python中的几种函数
Nov 03 Python
Python lxml解析HTML并用xpath获取元素的方法
Jan 02 Python
Python自定义一个类实现字典dict功能的方法
Jan 19 Python
Python实现带下标索引的遍历操作示例
May 30 Python
Python3.7在anaconda里面使用IDLE编译器的步骤详解
Apr 29 Python
Python绘制动态水球图过程详解
Jun 03 Python
Python中Selenium库使用教程详解
Jul 23 Python
python代码实现备忘录案例讲解
Jul 26 Python
Python 恐龙跑跑小游戏实现流程
Feb 15 Python
django在保存图像的同时压缩图像示例代码详解
Feb 11 #Python
Python中包的用法及安装
Feb 11 #Python
使用Python实现牛顿法求极值
Feb 10 #Python
关于TensorFlow新旧版本函数接口变化详解
Feb 10 #Python
TensorFlow 多元函数的极值实例
Feb 10 #Python
给 TensorFlow 变量进行赋值的方式
Feb 10 #Python
Python 中的pygame安装与配置教程详解
Feb 10 #Python
You might like
Yii2.0中使用js异步删除示例
2017/03/10 PHP
php使用curl_init()和curl_multi_init()多线程的速度比较详解
2018/08/15 PHP
php ActiveMQ的安装与使用方法图文教程
2020/02/23 PHP
PHP中的异常处理机制深入讲解
2020/11/10 PHP
文本框的字数限制功能jquery插件
2009/11/24 Javascript
JavaScript实现鼠标滑过处生成气泡的方法
2015/05/16 Javascript
JS实现按比例缩放图片的方法(附C#版代码)
2015/12/08 Javascript
AngularJs Understanding the Controller Component
2016/09/02 Javascript
Angular+Bootstrap+Spring Boot实现分页功能实例代码
2017/07/21 Javascript
jquery tmpl模板(实例讲解)
2017/09/02 jQuery
vuejs 切换导航条高亮(路由菜单高亮)的方法示例
2018/05/29 Javascript
Python 随机生成中文验证码的实例代码
2013/03/20 Python
Python中if __name__ == &quot;__main__&quot;详细解释
2014/10/21 Python
在阿里云服务器上配置CentOS+Nginx+Python+Flask环境
2016/06/18 Python
python利用dir函数查看类中所有成员函数示例代码
2017/09/08 Python
用Python删除本地目录下某一时间点之前创建的所有文件的实例
2017/12/14 Python
python scatter散点图用循环分类法加图例
2019/03/19 Python
浅析Python语言自带的数据结构有哪些
2019/08/27 Python
在Python中利用pickle保存变量的实例
2019/12/30 Python
Python基础之函数原理与应用实例详解
2020/01/03 Python
paramiko使用tail实时获取服务器的日志输出详解
2020/12/06 Python
详解HTML5中的picture元素响应式处理图片
2018/01/03 HTML / CSS
实习老师离校感言
2014/02/03 职场文书
士力架广告词
2014/03/20 职场文书
学生会主席竞聘书
2014/03/31 职场文书
医学专业大学生求职信
2014/07/12 职场文书
党支部组织生活会整改方案
2014/09/30 职场文书
小学校园广播稿集锦
2014/10/04 职场文书
拾金不昧表扬稿大全
2015/05/05 职场文书
廉政党课工作报告案例
2019/06/21 职场文书
WordPress多语言翻译插件 - WPML使用教程
2021/04/01 PHP
基于Python绘制子图及子图刻度的变换等的问题
2021/05/23 Python
OpenCV-Python模板匹配人眼的实例
2021/06/08 Python
Python上下文管理器Content Manager
2021/06/26 Python
MySQL基础快速入门知识总结(附思维导图)
2021/09/25 MySQL
Python中super().__init__()测试以及理解
2021/12/06 Python