【问题标题】:How can I select one object per each related object in django?如何在 django 中为每个相关对象选择一个对象?
【发布时间】:2013-03-19 15:23:37
【问题描述】:

如果我有两个班级:

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

class Item(models.Model):
    group = models.ForeignKey(Group)
    published = models.DateTimeField(auto_now_add=True)

如何创建查询集以从每个组中选择最新发布的项目?我想应该是这样的

Item.objects.order_by('published').distinct('group')

但我不能让它工作。

【问题讨论】:

    标签: django django-queryset


    【解决方案1】:

    models.py

    class Group(models.Model):
        name = models.CharField(max_length=100)
    
        def __unicode__(self):
            return self.name
    
        def latest_published(self):
            items = Item.objects.filter(group=self)[:1]
            for item in items:
                return item.published
            return ''
    
    class Item(models.Model):
        group = models.ForeignKey(Group)
        published = models.DateTimeField()
    
        def __unicode__(self):
            return "{0}".format(self.published)
    
        class Meta:
            ordering = ('-published',)
    

    views.py

    def myview(request):
        groups = Group.objects.filter()
    
        [.........]
    

    模板

    {% for group in groups %}
        {{group}} - {{group.latest_published}}<br/>
    {% endfor %}
    

    【讨论】:

    • 对不起,我不明白。我以为 Item.objects.filter(group=self)[:1] 只会返回一个对象?
    • @ersran9 来自问题How can I make a QuerySet to select the latest published Item from each Group?。这个查询Item.objects.filter(group=self)[:1]返回每个组中最新发布的条目(一个条目)
    • 嗯,您的代码不是也返回单个项目吗?因为你在循环中return
    • @ersran9 每组一项,这是要求
    【解决方案2】:

    如果您不介意将所有项目从数据库加载到内存中,并且希望在单个查询中完成,那么您可以这样做。在我的场景中,大约有 8 个“项目”和大约 4 个“组”,所以这样做几乎不会影响性能。

    from itertools import groupby
    
    items = [list(g)[0] for k, g in groupby(Item.objects.all().order_by('group', '-published'), lambda x: x.group_id)]
    

    如果您希望能够访问组对象,请将.select_related('group') 添加到内部查询集。

    它在做什么?

    1. 获取所有项目的查询集
    2. 按组对项目进行分组
    3. 从每个组中挑选第一个项目,并将它们放入一个列表中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-18
      • 2023-03-18
      相关资源
      最近更新 更多