Django ORM,按组/文件夹列出的最新项目/邮件

2024-04-25 22:31:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用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创建此查询?谢谢。你知道吗


Tags: django模型messagemodeltitlemodelsfolderlength
2条回答

要获得更好的性能,可以尝试使用^{}

# 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>

或者可以查看模板中的^{}。你知道吗

免责声明:此代码是用类似的模型结构测试的,而不是在模板中,因此,您可能需要做一些小的更改。满足你的需要。你知道吗

您可以在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 %}

更新以减少对数据库的查询数:

如果要减少查询数,可以将^{}对象与自定义queryset一起使用:

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

相关问题 更多 >