我有一个包含一些数据的文件——data.txt(存在于正确的本地化中)。我希望 django 应用程序在启动应用程序之前处理此文件并对每次更改做出反应(无需重新启动)。最好的方法是什么?
问问题
232 次
4 回答
3
对于启动,您可以编写在init中执行所需操作的中间件,然后从init中引发 django.core.exceptions.MiddlewareNotUsed ,因此 django 不会将其用于任何请求处理。文档
中间件init将在启动时调用,而不是在第一次请求时调用。至于对文件更改的反应,您可以使用https://github.com/gorakhargosh/watchdog(可以在此处找到使用示例)。所以你也可以在中间件的某个地方启动它,或者如果它只有数据库更新,你可以创建一个单独的脚本(或 django 管理命令),它将通过主管或类似的东西运行,并将监视这个文件并更新数据库。
于 2013-04-24T11:29:04.210 回答
1
也许您可以在设置中放置一个对象,该对象将在每次更改时查找文件。...即:创建一个类,该类将加载文件并在修改后重新加载该文件
class ExtraConfigWatcher(object):
def __init__(self, file):
self.file = file
self.cached = dict()
self.last_date_modified = None
def update_config(self):
"""
update the config by reloading the file
"""
if has_been_modified(self.file, self.last_date_modified):
# regenerate the config with te file.
self.cached = get_dict_with_file(self.file)
self.last_date_modified = time.time()
def __getitem__(self, *args, **kwargs):
self.update_config()
return self.cached.__getitem__(*args, **kwargs)
def __setitem__(self, *args, **kwargs):
raise NotImplemented("you can't set config into this")
在settings.py中:初始化这个对象
EXTRA_CONFIG = ExtraConfigWatcher("path/to/the/file.dat")
在 myapps/views.py 中:导入设置并使用 EXTRA_CONFIG
from django.conf import settings
def dosomthing(request):
if settings.EXTRA_CONFIG["the_data_from_the_file"] == "foo":
# bouhh
于 2013-04-25T07:46:00.490 回答
1
不久前,我试图找到一种“热交换”Python 模块的机制。虽然这不是您所需要的,但也许您可以使用我提出的实现,并监视您的配置文件以进行修改并采取相应的行动。
我提出的代码如下(我没有使用 inotify,因为我在 NFS 文件系统中工作):
import imp
import time
import hashlib
import threading
import logging
logger = logging.getLogger("")
class MonitorThread(threading.Thread):
def __init__(self, engine, frequency=1):
super(MonitorThread, self).__init__()
self.engine = engine
self.frequency = frequency
# daemonize the thread so that it ends with the master program
self.daemon = True
def run(self):
while True:
with open(self.engine.source, "rb") as fp:
fingerprint = hashlib.sha1(fp.read()).hexdigest()
if not fingerprint == self.engine.fingerprint:
self.engine.notify(fingerprint)
time.sleep(self.frequency)
class Engine(object):
def __init__(self, source):
# store the path to the engine source
self.source = source
# load the module for the first time and create a fingerprint
# for the file
self.mod = imp.load_source("source", self.source)
with open(self.source, "rb") as fp:
self.fingerprint = hashlib.sha1(fp.read()).hexdigest()
# turn on monitoring thread
monitor = MonitorThread(self)
monitor.start()
def notify(self, fingerprint):
logger.info("received notification of fingerprint change ({0})".\
format(fingerprint))
self.fingerprint = fingerprint
self.mod = imp.load_source("source", self.source)
def __getattr__(self, attr):
return getattr(self.mod, attr)
def main():
logging.basicConfig(level=logging.INFO,
filename="hotswap.log")
engine = Engine("engine.py")
# this silly loop is a sample of how the program can be running in
# one thread and the monitoring is performed in another.
while True:
engine.f1()
engine.f2()
time.sleep(1)
if __name__ == "__main__":
main()
于 2013-04-25T20:23:49.203 回答