我正在寻找建议和最大的Django方式将大型可变内容(比如大量10,000行列表)逐个部分加载到用户页面,以便在用户要求更多之前仅显示一些行。
这是一个详细的场景(我希望它对你有用。这只是一个帮助处理大型模板变量和分页的简单例子):
dosearch函数做了类似的事情:
dosearch(FILE, pattern):
result = []
fh = open(FILE, 'r')
for line in fh:
if re.match(pattern, line):
result.append(line)
return result
现在,结果是一个列表,根据模式,可能非常大(例如10-20MB)。现在完成文件的处理,我想向用户显示“result”变量。 HTTP发布后,用户将被重定向到website.com/parsed。
您可以想象,我在第7步中的目标是在HTTP POST后将此变量返回给用户。但由于“结果”变量可能很大,我不想直接将10,000行输出转储到页面。我想要实现的是前200行显示的方式,当用户向下滚动时,一旦用户到达页面底部,就会加载另外200行。
为简单起见,请忽略滚动部分。用户还可以使用[NEXT]按钮单击并加载其他200个条目,依此类推。
Django实现这一目标的方法是什么?我是否需要将结果变量保存到数据库并使用Ajax?
还假设多个用户将使用完全相同的页面/网站,因此我需要能够区分同时搜索两个不同文件的两个用户。
当用户导航时,应该从内存中销毁生成的“result”变量。
答案 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
指定行的顺序。
在结果视图中,您可以使用pagination或generic ListView
来显示第一行,或使用AJAX获取更多行。
您需要添加删除按钮以清除此模型中的用户数据,或运行定期作业(可能使用crontab
和custom 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以编码格式存储)。