首页 > 解决方案 > 在 Django 应用程序中一直在后台运行的函数(以及启动本身)

问题描述

我创建了简单的 Django 应用程序。在这个应用程序中,我有一个复选框。如果在数据库中签入此复选框状态,我会将其保存到数据库中,True如果未选中复选框,则我False有价值。这部分没有问题。现在我创建了一个函数,它每 10 秒为我打印一次,这个复选框状态值一直来自数据库。

我放入views.py文件的函数,它看起来像:

def get_value():
    while True:
        value_change = TurnOnOff.objects.first()
        if value_change.turnOnOff:
            print("true")
        else:
            print("false")
        time.sleep(10)

关键是该功能应该一直有效。例如,如果我在运行命令后输入models.py代码,它应该给我这样的输出:checkbox = models.BooleanField(default=False)python manage.py runserver

Performing system checks...

System check identified no issues (0 silenced).
January 04, 2019 - 09:19:47
Django version 2.1.3, using settings 'CMS.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
true
true
true
true

那么如果我访问网站并更改状态应该打印 false 这很明显。但是您注意到问题是如何启动此方法。即使我还没有访问该网站,它也应该一直有效。这部分让我感到困惑。如何正确地做到这一点?

我需要承认我尝试了一些解决方案

但是这个解决方案不起作用。

中间件类:

class SimpleMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        get_value()

标签: pythondjangobackground-processstartup

解决方案


您可以通过使用AppConfig.ready()钩子并将其与子进程/线程组合来实现此目的。

这是一个示例apps.py文件(基于教程Polls应用程序):

import time
from multiprocessing import Process

from django.apps import AppConfig
from django import db



class TurnOnOffMonitor(Process):
    def __init__(self):
        super().__init__()
        self.daemon = True

    def run(self):
        # This import needs to be delayed. It needs to happen after apps are
        # loaded so we put it into the method here (it won't work as top-level
        # import)
        from .models import TurnOnOff

        # Because this is a subprocess, we must ensure that we get new
        # connections dedicated to this process to avoid interfering with the
        # main connections. Closing any existing connection *should* ensure
        # this.
        db.connections.close_all()

        # We can do an endless loop here because we flagged the process as
        # being a "daemon". This ensures it will exit when the parent exists
        while True:
            value_change = TurnOnOff.objects.first()
            if value_change.turnOnOff:
                print("true")
            else:
                print("false")
            time.sleep(10)


class PollsConfig(AppConfig):
    name = 'polls'
    def ready(self):
        monitor = TurnOnOffMonitor()
        monitor.start()

推荐阅读