如何在django中为每个相关对象选择一个对象?

时间:2013-03-19 15:23:37

标签: django django-queryset

如果我有两个班级:

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

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

如何让QuerySet从每个组中选择最新发布的项目?我想它应该像

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

但我不能让它发挥作用。

2 个答案:

答案 0 :(得分:2)

<强> 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 %}

答案 1 :(得分:0)

如果您不介意将所有项目从数据库加载到内存中,并且您希望在单个查询中执行此操作,则可以执行此操作。在我的场景中,大约有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. 从每个组中挑选第一个项目,并将它们放入列表中。