首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用Django的ORM拉取随机记录?

如何使用Django的ORM拉取随机记录?
EN

Stack Overflow用户
提问于 2009-06-07 19:25:16
回答 9查看 98K关注 0票数 191

我有一个模型,代表我在我的网站上展示的绘画。在主网页上,我想展示其中的一些:最新的,大多数时间没有访问的,最受欢迎的和随机的。

我使用的是Django 1.0.2。

虽然前3个模型很容易使用django模型来提取,但最后一个(随机)给我带来了一些麻烦。我可以在我的视图中对其进行ofc编码,如下所示:

代码语言:javascript
复制
number_of_records = models.Painting.objects.count()
random_index = int(random.random()*number_of_records)+1
random_paint = models.Painting.get(pk = random_index)

但在我看来,它看起来不像是我想要的东西--这完全是数据库抽象的一部分,应该在模型中。此外,在这里,我需要处理删除的记录(然后所有记录的数量将不会涵盖我所有可能的键值),可能还有很多其他事情。

有没有其他的选择,最好是在模型抽象里面?

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2010-01-23 00:27:08

使用order_by('?')将在生产的第二天杀死数据库服务器。一种更好的方法是类似于Getting a random row from a relational database中描述的方法。

代码语言:javascript
复制
from django.db.models.aggregates import Count
from random import randint

class PaintingManager(models.Manager):
    def random(self):
        count = self.aggregate(count=Count('id'))['count']
        random_index = randint(0, count - 1)
        return self.all()[random_index]
票数 186
EN

Stack Overflow用户

发布于 2009-06-07 19:54:51

只需使用:

代码语言:javascript
复制
MyModel.objects.order_by('?').first()

它在QuerySet API中有文档记录。

票数 281
EN

Stack Overflow用户

发布于 2009-06-09 18:16:49

使用order_by('?'):N的解决方案非常慢,即使对于中等大小的表,如果您使用MySQL (不了解其他数据库)。

order_by('?')[:N]将被转换为SELECT ... FROM ... WHERE ... ORDER BY RAND() LIMIT N查询。

这意味着对于表中的每一行,都将执行RAND()函数,然后根据该函数的值对整个表进行排序,然后返回前N条记录。如果您的表很小,这是很好的。但在大多数情况下,这是一个非常慢的查询。

我写了一个简单的函数,即使id有空洞也能工作(删除了一些行):

代码语言:javascript
复制
def get_random_item(model, max_id=None):
    if max_id is None:
        max_id = model.objects.aggregate(Max('id')).values()[0]
    min_id = math.ceil(max_id*random.random())
    return model.objects.filter(id__gte=min_id)[0]

它比order_by('?')更快几乎在所有的情况下。

票数 26
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/962619

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档