我有一个QuerySet,如:
items = Item.objects.all()
项目有一个'名称'字段。在我想要显示的模板中:
所以这些物品是按照第一个字母排序和分组的。遗漏的字母被省略。有没有人有任何想法?
答案 0 :(得分:19)
如果您关心的是它在页面上的显示,那么就有一个模板标签。首先,在课堂上定义组织原则。在你的情况下,这是第一个字母:
class Item(models.Model):
...
def first_letter(self):
return self.name and self.name[0] or ''
然后使用first_letter调用在模板中定义重组:
{% regroup items by first_letter as letter_list %}
<ul>
{% for letter in letter_list %}
<li>{{ letter.grouper }}
<ul>
{% for item in letter.list %}
<li>{{ item.name }}</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
答案 1 :(得分:6)
只是想补充一点,如果您使用此项并且您的项目具有小写的第一个字符,那么它将是一个单独的组。我加了鞋面。
return self.name and self.name.upper()[0] or ''
答案 2 :(得分:5)
或者,您可以在模板中使用slice
内联,而无需在模型上使用first_letter
方法。
{% regroup items by name|slice:":1" as letter_list %}
<ul>
{% for letter in letter_list %}
<li>{{ letter.grouper }}
<ul>
{% for item in letter.list %}
<li>{{ item.name }}</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
答案 3 :(得分:0)
更容易。您可以在'重新组合'中首先进行分组:
{% regroup items|dictsort:"name" by name.0 as item_letter %}
<ul>
{% for letter in item_letter %}
<h4>{{ letter.grouper|title }}</h4>
{% for i in letter.list|dictsort:"name" %}
<li>{{ i.name }}</li>
{% endfor %}
{% empty %}
<span>There is no items yet...</span>
{% endfor %}
</ul>
在这种情况下, name.0
与Python中的item.name[0]
相同。
在Django 1.10中测试
答案 4 :(得分:0)
对于Django REST,你可以这样做,
import string
import collections
from rest_framework.response import Response
from rest_framework import status, viewsets
def groupby(self, request):
result = []
for i in list(string.ascii_uppercase):
c = City.objects.filter(name__startswith=i)
if c:
result.append((i, map((lambda x: x['name']),list(c.values('name')))
))
return Response(collections.OrderedDict(sorted(dict(result).items())), status=status.HTTP_200_OK)
class City(models.Model):
"""All features model"""
name = models.CharField(max_length=99)
{
"A": [
"Adelanto",
"Azusa",
"Alameda",
"Albany",
"Alhambra",
"Anaheim"
],
"B": [
"Belmont",
"Berkeley",
"Beverly Hills",
"Big Sur",
"Burbank"
],
......
}
答案 5 :(得分:0)
这是直接使用Django和Python的另一种做法。提供的另一种解决方案效率很低
import itertools
collector = {}
item_qs = Item.objects.all().order_by('name')
for alphabet_letter, items in itertools.groupby(item_qs, lambda x: x.name[0].lower()):
# you can do any modifications you need at this point
# you can do another loop if you want or a dictionary comprehension
collector[alphabet_letter] = items
这给你什么?一次查询数据库。
我应该使用collector
吗?不,您可能应该使用yield
,这只是概念的证明。
无论您做什么,都不要不要在循环内添加查询调用。