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