当前位置:  开发笔记 > 后端 > 正文

如何在Django中使用分页对一组对象进行"随机"排序?

如何解决《如何在Django中使用分页对一组对象进行"随机"排序?》经验,为你挑选了1个好方法。

我有一个包含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在每个用户会话中创建一次?



1> Jordan Reite..:

这些究竟是多么随机?它是否必须为每个用户不同,还是仅仅是随机性的外观是重要的?

如果是后者,那么您可以简单地添加一个调用ordering相关模型的字段,并用随机整数填充它.

否则,除非记录集很小(并且,鉴于它正在被分页,我对此表示怀疑),然后为每个会话存储单独的随机查询集可能会非常快速地成为内存问题,除非您知道用户群非常小.这是一种模仿随机性的可能解决方案,但实际上只创建了5个随机集:

import random
from django.core import cache
RANDOM_EXPERIENCES=5

def my_view(request):
    if not request.session.get('random_exp'):
        request.session['random_exp']=random.randrange(0,RANDOM_EXPERIENCES)
    object_list = cache.get('random_exp_%d' % request.session['random_exp'])
    if not object_list:
        object_list = list(Object.objects.all().order_by('?'))
        cache.set('random_exp_%d' % request.session['random_exp'], object_list, 100)
    paginator = Paginator(object_list, 10)
    page = 1 # or whatever page we have
    display_list = paginator.page(page)
    ....

在此示例中,不是为每个用户创建单独的查询集(导致存储中可能存在数千个查询集),而是将其存储在request.session中(比缓存更低效的存储机制,可以将其设置为使用非常高效的东西,像memcached一样,我们现在只有5个查询集存储在缓存中,但希望对大多数用户来说是足够随机的体验.如果您想要更多随机性,增加RANDOM_EXPERIENCES的值应该会有所帮助.我认为你可能会高达100,几乎没有性能问题.

如果记录本身不经常更改,则可以为缓存设置极高的超时.

更新

这是一种实现它的方法,它使用稍多的内存/存储但确保每个用户可以"保持"它们的查询集而不会出现其缓存超时的危险(假设3小时足够长以查看记录).

import datetime

...

    if not request.session.get('random_exp'):
        request.session['random_exp']="%d_%d" % ( 
            datetime.datetime.strftime(datetime.datetime.now(),'%Y%m%dH'),
            random.randrange(0, RANDOM_EXPERIENCES)
        )
    object_list = cache.get("random_exp_%s" % request.session['random_exp'])
    if not object_list:
        object_list = list(Object.objects.all().order_by('?'))
        cache.set(cache_key, "random_exp_%s" % request.session['random_exp'], 60*60*4)

在这里,我们创建一个不会超时4小时的缓存查询集.但是,request.session键设置为年,月,日和小时,以便有人进入该时刻的记录集当前.任何已经查看过查询集的人都可以在到期之前至少再看3个小时(或者只要他们的会话仍处于活动状态).最多,将在缓存中存储5*RANDOM_EXPERIENCES个查询集.

推荐阅读
ERIK又
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有