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

时间:2019-03-14 10:28:05

标签: python django django-tables2

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

为此,我在models.py中创建了一个ReportEntry类。

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"

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

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:\Apps\Python3702\my_venv\web\mysite\db.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()

此Web应用程序正常运行。

现在,我想使用下面的Python脚本在SQLite数据库中插入一个新条目(假设我想更新进程的状态)

isUnique(value) {
  return db.collection('users')
  .where('username', '==', value)
  .get({source: 'cache'})
  .then((snapshot) => {
    console.log(snapshot, snapshot.size, snapshot.docs)

    return snapshot.size === 0
  })

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

是否有一种“简便”的方法可以以某种方式定期从数据库中重新加载数据,而无需使用redis / celery和类似的应用程序?

2 个答案:

答案 0 :(得分:1)

问题在于您在类级别上显式地执行查询,

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

尽管有名称,在这里您不是在定义一个查询集(它是惰性的,并根据需要进行更新),而是一个具体的项目列表,每个过程仅评估一次。不要这样做。

相反,请定义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]

答案 1 :(得分:1)

由于这两行,数据没有刷新:

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

解析视图的代码时,它们中的每一个都会求值一次。发生这种情况是因为您要将查询集转换为列表。我不确定您的refresh字段的工作原理,因为您没有提供任何使用它的代码,但是对于queryset,至少有两种可能的解决方案。

第一个解决方案是重写您的查询集,因此它将仍然是查询集,而不是列表。 Django知道如何处理视图中的查询集,以使其表现为“惰性”(在每个视图上进行评估而不是一次评估),但是它无法使用列表来做到这一点。您的新查询集如下所示:

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

请注意,与字段不同并不适用于每个数据库后端。

第二种解决方案是将查询集移至get_queryset方法:

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