您好,登錄后才能下訂單哦!
對于任何軟件開發人員而言,為將來計劃任務都是必不可少的工具。 盡管我們創建的許多編程旨在響應明確的觸發或用戶事件,但定期執行的后臺進程也同樣重要。
“每個星期一早晨更新結果。”
“每天晚上分批下單。”
甚至具有每日請求限制的第三方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 > <h6>Currently in</h6> <h4>{{city}}</h4> <h5>{{temperature_in_f}} F | {{temperature_in_c}} C</h5> <h5>{{desctiprion}}</h5> <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 執行計劃任務的實現方法,希望對大家有所幫助!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。