根据属性值从数据库中检索随机记录,直到达到限制为止;如果未达到限制,则与其他操作一起完成

时间:2018-11-03 08:52:42

标签: django postgresql django-queryset

我将Django与Postgres一起使用。

在页面上,我可以显示特色商品列表,比如说10。

  1. 如果在数据库中我有超过10个特色项目,我想让它们随机/(更好地旋转)。

  2. 如果特色商品的数量少于10,请获取所有特色商品并添加到列表中,直到10个非特色商品。

由于随机处理会花费更多时间在数据库上,因此我在python中进行采样:

count = Item.objects.filter(is_featured=True).count()

        if count >= 10:
            item = random.sample(list(Item.objects.filter(is_featured=True))[:10])
        else:
            item = list(Item.objects.all()[:10])

上面的代码错过了特征少于10个的情况(例如8个,增加了2个非特征)。

我可以尝试添加一个新查询,但是我不知道这是否是有效的检索,为此使用了4-5个查询。

2 个答案:

答案 0 :(得分:1)

我能找到的最佳解决方案是:

 from itertools import chain
 items = list(chain(Item.objects.filter(is_featured=True).order_by('?'), Item.objects.filter(is_featured=False).order_by('?')))[:10]

通过这种方式,查询集的顺序得以保留,但缺点是items成为列表而不是查询集。您可以在此SO Answer中查看更多详细信息。仅供参考:有一些很棒的解决方案,例如使用Q或管道,但它们不保留查询集的顺序。

答案 1 :(得分:1)

SQL方法:您可以使用如下SQL语句来实现:

SELECT      uuid_generate_v4(), *
FROM        table_name
ORDER BY    NOT is_featured, uuid_generate_v4()
LIMIT 10;

说明:生成的UUID应该模拟随机性(就电子商务而言,这足够了)。当按NOT is_featured对行进行排序时,会将is_featured行放在最前面;并自动将行减少到10个限制(如果用完了特色项目)。