我将Django与Postgres一起使用。
在页面上,我可以显示特色商品列表,比如说10。
如果在数据库中我有超过10个特色项目,我想让它们随机/(更好地旋转)。
如果特色商品的数量少于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个查询。
答案 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个限制(如果用完了特色项目)。