【问题标题】:Django ORM. Retrieve 10 items for each categoryDjango ORM。检索每个类别的 10 个项目
【发布时间】:2019-04-26 18:00:41
【问题描述】:

我的 Django REST 中有 2 个模型。

class Category(models.Model):
    name = models.CharField()

class Item(models.Model):
    name = models.CharField()
    category = models.ForeignKey(Category)

我需要构建查询集,每个类别都有 10 个项目。 我不知道我需要筛选类别或项目,但也许有人可以帮助我。

我想我需要这样的东西: Item.objects.filter.. 如果相同类别的项目不 > 10。

如果有人告诉我一些方法或决定,我会很高兴。

【问题讨论】:

    标签: django django-rest-framework django-queryset django-orm


    【解决方案1】:

    很简单:

     for cat in Category.objects.all():
         if items is null:
             items = Item.objects.filter(category=cat)[:10]
         items += Item.objects.filter(category=cat)[:10]
    

    如果您需要单个查询,则必须编写自己的自定义 SQL - 请参阅 Select top 10 records for each category

    【讨论】:

    • 嗯...它不正确。我想要我拥有的每个类别的 10 个项目。例如,我有类别 1 和 2。第一个类别有 150 个项目,第二个有 390 个。我想要查询集,它为每个类别提供 10 个项目。你的回答给了我一个类别的 10 个项目。
    • 我认为它向 db 发送了很多请求(也许它可能只对 db 执行一个请求?
    【解决方案2】:

    看起来如果您没有太多类别,最简单的方法是选择所有类别(或其中的一个子集),然后遍历它们并从每个类别中选择 10 个项目

    items = []
    
    categories = Category.objects.all()
    for category in categories:
        items.extend(list(Item.objects.filter(category=category)[:10]))
    

    【讨论】:

    • 是的,它很简单,但是对 db 的请求太多了。
    • 这会获取类别中的所有项目并将它们转换为列表
    • 另一种思考方式是从原始 sql 开始,然后转向 django 查询代码。您会得到“从 .... 限制 10 的项目中选择 *”。 “limit”子句限制整个结果集,您不能为每个过滤器设置限制(在 where 子句中)。您可以使用连接执行类似的操作,但您必须知道类别的数量才能为每个类别单独连接。
    • 您必须编写自己的自定义 SQL 以减少查询数量 - 请参阅 stackoverflow.com/questions/176964/…
    • 因此可以尝试选择类别,然后在 django 中迭代它们生成查询。我会试着考虑一下。
    【解决方案3】:

    你可以试试这个:

    items = {}
    
    categories = Category.objects.prefetch_related('item_set').all()
    for category in categories:
        items[category.name] = list(category.item_set.all()[:10])
    

    prefetch_related 方法将为您提供类别项目而无需不必要的数据库请求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-27
      • 2019-10-11
      • 2017-07-13
      • 2018-11-03
      • 2019-11-24
      • 1970-01-01
      • 2015-02-07
      • 1970-01-01
      相关资源
      最近更新 更多