【问题标题】:Django ORM - Get N random records, and then split them in 2 groupsDjango ORM - 获取 N 条随机记录,然后将它们分成 2 组
【发布时间】:2018-02-15 11:41:30
【问题描述】:

我有一个 Post 模型:

class Post(models.Model):
    headline = models.CharField(max_length=255)
    ...

我没有成功地试图实现的是获得两个随机组,每组 5 个帖子,其中第二组记录了第一组没有的帖子。

现在我知道如何使用 Python 做到这一点,但我想知道是否有更优雅、类似 ORM 的解决方案。

我尝试了以下方法:

posts = Post.objects.all().order_by('?')
first_group = posts[:5]
second_group = posts[5:]

但这有时会在两个组中返回相同的帖子。

我还试图欺骗系统执行以下操作:

posts = Post.objects.all().order_by('?')
first_group = posts[:5]
second_group = Post.objects.exclude(id__in=first_group)

但还是没有运气。

谁能给我一些指示,这样我就不必在纯 Python 中循环记录?

【问题讨论】:

    标签: python django django-orm


    【解决方案1】:

    要获得独特的帖子,您可以:

    posts = list(Post.objects.all().order_by('?')[:10])
    first_group = posts[:5]
    second_group = posts[5:]
    

    这具有进行单个数据库查询的额外优势。

    【讨论】:

    • 太棒了!!它就像一个魅力。非常感谢。将查询集转换为列表非常聪明:)
    【解决方案2】:

    参考Django官方文档(https://docs.djangoproject.com/en/2.0/topics/db/queries/#querysets-are-lazy),QuerySet是懒惰的。

    这意味着在您迭代 QuerySet 之前,QuerySet 不会将任何查询传递给 DB。

    所以如果你想得到查询结果列表,你必须先迭代查询集。

    posts = Post.objects.all().order_by('?')
    first_group = []
    second_group = []
    
    iterate_count = 0
    for post in posts:
        if iterate_count < 5:
            first_group.append(post)
        elif iterate_count < 10:
            second_group.append(post)
        else:
            break
    

    也许,上面的代码可以正常工作。

    【讨论】:

      猜你喜欢
      • 2017-10-04
      • 1970-01-01
      • 2013-12-31
      • 2020-06-14
      • 2018-02-22
      • 2016-05-06
      • 2022-12-07
      • 2010-11-01
      相关资源
      最近更新 更多