使用滚动

时间:2018-06-05 10:50:56

标签: django

我正在寻找建议和最大的Django方式将大型可变内容(比如大量10,000行列表)逐个部分加载到用户页面,以便在用户要求更多之前仅显示一些行。

这是一个详细的场景(我希望它对你有用。这只是一个帮助处理大型模板变量和分页的简单例子):

  1. 用户访问我的Django后端托管的website.com/searchfiles并作为模板返回
  2. searchfiles.html模板包含一个带有选择下拉菜单的表单,以便选择服务器上已存在的文件(比如有20个海量日志文件)。在下拉菜单下方有一个文本框,允许用户输入正则表达式字符串。所以表格中只有两个项目。
  3. P.S。每个文件通常都很大,例如20-30MB
  4. 当用户选择文件并在文本框中输入正则表达式并单击“提交”时,将发出HTTP POST
  5. Django后端接收POST,读取文件名+ regexp字符串并执行函数dosearch(FILE,pattern)
  6. dosearch函数做了类似的事情:

    dosearch(FILE, pattern):
        result = []
        fh = open(FILE, 'r')
        for line in fh:
            if re.match(pattern, line):
                result.append(line)
        return result
    
  7. 现在,结果是一个列表,根据模式,可能非常大(例如10-20MB)。现在完成文件的处理,我想向用户显示“result”变量。 HTTP发布后,用户将被重定向到website.com/parsed。

  8. 您可以想象,我在第7步中的目标是在HTTP POST后将此变量返回给用户。但由于“结果”变量可能很大,我不想直接将10,000行输出转储到页面。我想要实现的是前200行显示的方式,当用户向下滚动时,一旦用户到达页面底部,就会加载另外200行。

    为简单起见,请忽略滚动部分。用户还可以使用[NEXT]按钮单击并加载其他200个条目,依此类推。

    Django实现这一目标的方法是什么?我是否需要将结果变量保存到数据库并使用Ajax?

    还假设多个用户将使用完全相同的页面/网站,因此我需要能够区分同时搜索两个不同文件的两个用户。

    当用户导航时,应该从内存中销毁生成的“result”变量。

1 个答案:

答案 0 :(得分:1)

我可以想到两种可能性:

:一种。使用模型

class ResultLine(models.Model):
    user = models.ForeignKey(User)
    sequence_number = models.IntegerField()
    line = models.CharField(max_length=1000)
    created_at = models.DateTimeField(auto_now_add=True)

解析文件后,您将每个结果行存储为此模型的实例,使用sequence_number指定行的顺序。

在结果视图中,您可以使用paginationgeneric ListView来显示第一行,或使用AJAX获取更多行。

您需要添加删除按钮以清除此模型中的用户数据,或运行定期作业(可能使用crontabcustom management command)来删除旧的结果行。

<强> B中。使用会话数据

另一种可能性是将结果存储在用户会话中。

request.session['result_list'] = dosearch(FILE, pattern)

取决于session engine,可能存在尺寸限制; this post声明database-backed sessions仅受数据库引擎限制(这意味着您可以在会话中存储多个MB甚至GB数据。

此外,您的服务器需要足够的RAM来保存多个用户的整个结果列表。

稍后在结果视图中,您只需从会话中读取而不是从模型中读取。

性能方面存在差异:两种方法都将数据存储在数据库中(使用database-backed sessions),但选项A 允许您在结果视图中进行部分读取,而< strong>选项B 总是在每个请求中将整个结果列表读入内存(因为整个会话dict以编码格式存储)。