Django ORM,最新 items/messages groups/folders

Django ORM, latest items/messages by groups/folders

我正在使用 Django 1.8,我有一些模型:

class Folder(models.Model):
    title = models.CharField( max_length=255 )

class Message(models.Model):
    title = models.CharField( max_length=255 )
    folder = models.ForeignKey( Folder )

我需要屏幕显示所有具有最新消息的文件夹(如 10 个),例如:

F1:    F2:   F3:
 m1     m3    m6
 m2     m4    ..
 m3     m5    ..
              m10

如何使用 django-orm 创建此查询?谢谢

您可以在 Folder 模型中添加一个 property

class Folder(models.Model):
    title = models.CharField( max_length=255 )

    @property
    def latest_10_messages(self):
        # order by id decreasing and get top 10
        return self.message_set.order_by('-id')[:10]

然后,您可以在您的模板中使用它:

{% for folder in folders %}
    {{ folder.name }}

    {% for msg in folder.latest_10_messages %}
        {{ msg.title }}
    {% endfor %}
{% endfor %}

UPDATE减少对数据库的查询次数:

如果您想减少查询的数量,您可以使用带有自定义查询集的 Prefetch 对象:

prefetch_query = Prefetch('message_set__title', queryset=Message.objects.all().order_by('-id'), to_attr='message_titles')
folders = Folder.objects.all().prefetch_related(prefetch_query)

然后在模板中使用 slice 获得前 10 名:

{% for folder in folders %}
    {{ folder.name }}

    {% for msg in folder.message_titles|slice":10" %}
        {{ msg }}
    {% endfor %}
{% endfor %}

为了获得更好的性能,您可以尝试使用 prefetch_related:

# get the folders
folders = Folder.objects.all().prefetch_related('message_set')

# create a result list
result = []

# populate result list
result = [{'folder': f.title, 'messages': f.message_set.values('title').order_by('-id')[:10]} for f in folders]

# every f.message_set... won't hit database, because of prefetch_related

然后在您的模板中:

<ul>
  {% for res in result %}
    <li>
      {% for message in res.messages %}
        {{ message.title }}
      {% endfor %}
    </li>
  {% endfor %}
</ul>

或者您可以查看模板中的 regroup

免责声明:这段代码是用类似的模型结构测试的,而不是在模板中,所以,也许你需要做一些小的改动。以满足您的需求。