我有一个有100个左右条目的模型--客户端希望这些条目以“随机”顺序出现,但也希望在那里分页。
def my_view(request):
object_list = Object.objects.all().order_by('?')
paginator = Paginator(object_list, 10)
page = 1 # or whatever page we have
display_list = paginator.page(page)
....
所以我的问题应该是--如何在每个用户会话中创建一次object_list
?
5条答案
按热度按时间x4shl7ld1#
这到底有多随机对于每个用户来说,它必须是不同的吗?或者仅仅是随机性的外观很重要?
如果是后者,那么您可以简单地将一个名为
ordering
的字段添加到所讨论的模型中,并使用随机整数填充它。否则,除非记录集很小(而且,考虑到它是分页的,我对此表示怀疑),否则为每个会话存储单独的随机查询集可能很快就会成为内存问题,除非您知道用户群非常小。这里有一个可能的解决方案,它模仿随机性,但实际上只创建5个随机集:
在这个例子中,我们没有为每个用户创建一个单独的查询集(导致存储中可能有数千个查询集)并将其存储在request.session中(一种比缓存效率更低的存储机制,可以设置为使用非常有效的东西,如memcached),我们现在只有5个查询集存储在缓存中,但希望对大多数用户来说足够随机。如果你想要更多的随机性,增加RANDOM_EXPERIENCES的值应该会有所帮助。我想你可能会上升到100高与一些性能问题。
如果记录本身很少更改,则可以为该高速缓存设置一个极高的超时。
更新
这里有一种实现它的方法,它使用稍微多一点的内存/存储,但确保每个用户都可以“持有”他们的查询集,而不会有缓存超时的危险(假设3小时足够长来查看记录)。
这里我们创建了一个缓存的查询集,它在4小时内不会超时。但是,request.session键设置为年、月、日和小时,以便进入的用户看到该小时的当前记录集。任何已经查看过该查询集的人都可以在它过期之前至少再看到3个小时(或者只要他们的会话仍然处于活动状态)。缓存中最多存储5*RANDOM_EXPERIENCES查询集。
hkmswyz62#
尝试使用默认的Django meta选项order_by?
打个问号“?“导致随机排序
https://docs.djangoproject.com/en/1.3/ref/models/options/#ordering
qpgpyjmq3#
@Jordan Reiter的解决方案真的很棒。但是在使用的时候有一个小问题。如果记录被更新,则需要一段时间才能生效。而且,如果记录的计数很大,它会使用太多的缓存空间。
我通过只缓存主键列来优化它。当记录更新时,它将立即生效。
c90pui9n4#
最好的做法可能是将查询集转换为列表,然后对其进行 Shuffle :
但是请注意,将查询集转换为列表将对其求值。如果Object表变得更大,这将成为性能的噩梦。
如果要存储这些对象,可以创建另一个表,并将用户id与对象id列表相关联,或者将100个左右的id存储在会话cookie中。对此,你能做的并不多:HTTP是无状态的,持久化可以通过使用cookie或数据存储(更可能是RDBS系统)来实现。
t5zmwmid5#
如果您只需要伪随机性,手动调用
setseed
就足够了(并且可以避免任何内存/性能问题):从此以后,你就可以像往常一样继续进行分页了。尽管随机性只会在查询集中的对象数量发生变化后才发生变化。这可以是想要的(例如,人们可以说“第二页上的第二个条目”,这在真实的的随机性下是完全不可能的)。你也可以尝试采用另一种种子方法,例如
seed = timezone.now().strftime("%m")
,每个月都有新的随机性。