【问题标题】:Randomize queryset deterministically确定性地随机化查询集
【发布时间】:2013-09-19 06:57:56
【问题描述】:

我在 Django 中有一个查询集:

Books.objects.filter(name=variable)

我想在我的用户中随机显示此列表(两个不同的用户不会以相同的顺序查看书籍)。但如果他多次返回,我希望同一用户的订单保持不变。

那么,给定一个特定于我的用户的整数(比如说他的 user.id),有没有办法随机化查询集?

非常感谢!

【问题讨论】:

    标签: python django


    【解决方案1】:

    你可以在数据库中随机化它:

    Books.objects.filter(name=variable).order_by('?')
    

    但最好将列表存储在缓存中,然后将缓存的列表随机化。

    出于开发目的,您可以在 settings.py 中使用虚拟缓存:

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
        }
    }
    

    在生产中,您应该使用supported cache

    设置完成后,在用户登陆的第一个视图的视图中,从数据库中获取项目并将它们存储在缓存中:

    import random
    
    from django.core.cache import cache
    
    @login_required
    def index(request):
       cache_key = '{0}-books'.format(request.user.pk)
       book_list = cache.get(cache_key)
       if not book_list:
          # There was nothing in the cache, so we fetch the items
          # and add them in the cache
    
          # Here we set it to expire after 3600 seconds (1 hour)
          book_list = list(Book.objects.filter(name=variable))
          random.shuffle(book_list)
          cache.set(cache_key, book_list, 3600)
    
    
       # the rest of your code
    

    【讨论】:

    • order_by('?') 的问题在于,对于多次返回的用户,我的查询集永远不会相同。缓存查询是一个很好的解决方案,但我正在寻找另一种方法。就像种子随机一样。
    • 如果将随机列表存储在缓存中,那么对于每个用户来说都是相同的(即,直到缓存过期)。
    【解决方案2】:

    您可以创建一个单独的random.Random 对象:

    from random import Random
    
    r = Random()
    r.seed(some_user_id)
    books = Books.objects.filter(name=variable)
    jumbled = sorted(books, key=lambda L: r.random())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-17
      • 1970-01-01
      • 1970-01-01
      • 2013-12-24
      • 2011-09-16
      • 1970-01-01
      相关资源
      最近更新 更多