Django:在SQLITE中更新后的网页上刷新数据



我正在准备一个应该监视不同过程状态的仪表板Web应用程序(在Django 2.1.7中)。

为此,我在Models.py.py

中创建了一个class exterentry
class ReportEntry(models.Model):
    process = models.CharField(max_length=30)
    received = models.DateTimeField(auto_now_add=True)
    status = models.SmallIntegerField(default=1)
    def refresh(self):
        self.refresh_from_db()
        self.save()

要查看仪表板,我正在使用django-tables2。view.py脚本包括

from .tables import SimpleTable
from django_tables2 import SingleTableView
from .models import ReportEntry
class TableView(SingleTableView):
    table_class = SimpleTable
    processes = ReportEntry.objects.values('process').distinct()
    queryset = [ReportEntry.objects.filter(**k).latest('received') for k in processes]
    refresh = [a.refresh() for a in ReportEntry.objects.all()]
    template_name = "simple_list.html"

此Web应用程序正常工作。

现在,我想使用下面的python脚本插入SQLite DB的新条目(假设我想更新该过程的状态)

from sqlite3 import connect
def create_connection(db_file):
    try:
        conn = connect(db_file)
        return conn
    except Exception as e:
       print(e)
    return None
if __name__ == '__main__':
    from datetime import datetime, timedelta
    database = r'C:AppsPython3702my_venvwebmysitedb.sqlite3'
    conn = create_connection(database)
    cur = conn.cursor()
    sql = '''INSERT INTO main.monitor_reportentry(process,received,status)
         VALUES(?,?,?)'''
    cur.execute(sql, ['test', datetime.now(), 1])
    conn.commit()
    conn.close()

当我执行脚本并将数据插入sqlite db时,我尝试用仪表板刷新网页,但内容未更新。唯一对我有用的是服务器的重新启动,这不是进行数据重新加载的一种方法。

是否有一种"简单"的方法可以以某种方式定期重新加载数据库中的数据,而无需使用Redis/Celery和类似的应用程序?

问题是您在班级级别明确进行查询,在这里:

queryset = [ReportEntry.objects.filter(**k).latest('received') for k in processes]

尽管有名称,但在这里您没有定义一个QuerySet(这将是懒惰的,并且根据需要进行更新),而是在每个过程中进行一次更新的项目列表。不要这样做。

相反,定义get_queryset()方法:

class TableView(SingleTableView):
    table_class = SimpleTable
    template_name = "simple_list.html"
    def get_queryset(self, *args, **kwargs):
        processes = ReportEntry.objects.values('process').distinct()
        return [ReportEntry.objects.filter(**k).latest('received') for k in processes]

数据由于这两行而不是令人耳目一新:

    queryset = [ReportEntry.objects.filter(**k).latest('received') for k in processes]
    refresh = [a.refresh() for a in ReportEntry.objects.all()]

当您的视图代码解析时,每个人都会评估一次。发生这种情况是因为您将QuerySets转换为列表。我不完全知道您的refresh字段的工作原理,因为您没有提供任何使用它的代码,但是对于queryset,至少有两个可能的解决方案。

第一个解决方案将是重写您的QuerySet,因此它仍然是QuerySet,而不是列表。Django知道如何在视图中处理QuerySet,因此它们的行为"懒惰"(在每个视图上而不是一次评估),但是它不能用列表来做到这一点。您的新QuerySet看起来像这样:

    queryset = ReportEntry.objects.filter(**k).order_by('received').distinct('process')

请注意,在每个数据库后端都不适用于字段。

第二个解决方案是将QuerySet移至get_queryset方法:

    def get_queryset(self, *args, **kwargs):
        return [ReportEntry.objects.filter(**k).latest('received') for k in processes]

最新更新