2010-11-11 21 views
12

我有這樣一個QuerySet:Django按第一個字母對queryset進行分組?

items = Item.objects.all() 

項目有一個 '名稱' 字段。在模板我想說明:

  • 一個
  • 酒精
  • 火箭筒
  • Ç
  • 硬幣
  • 墨盒
  • 小號
  • 個劍
  • 麻雀

所以項目由首字母排序和分組。缺少字母。有沒有人有任何想法?

回答

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> 
+0

謝謝你,親切的先生! :)模型內的那個方法是我的缺失位。 – Tudorizer 2010-11-11 06:21:44

+0

解決問題的方法很酷。看着混合http://stackoverflow.com/questions/4151631/django-grouping-queryset-by-first-letter/4151742#4151742和這一起https://djangosnippets.org/snippets/889/ – 2013-11-03 17:51:51

+4

你不' t需要該類上的方法,因爲您可以在重新組合標記中使用過濾器。你可以做'{%按名稱重組項目| first | upper as letter_list%}' – 2014-10-12 17:16:21

6

只是想補充一點,如果你用這個和你的項目有一個小寫的第一個字符它將是一個單獨的組。我增加了它。

return self.name and self.name.upper()[0] or '' 
4

另外,您可以使用內嵌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> 
+0

這個解決方案更好,恕我直言 – 2017-04-06 13:52:48

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> 

在這種情況下,相同的Python item.name[0]name.0

Django測試1.10

相關問題