1

我有一个看起来像这样的模型:

class ListEntry(models.Model):
    STATUS_CHOICES = (
        ('PL', _('Playing')),
        ('CO', _('Completed')),
        ('OH', _('On-hold')),
        ('DR', _('Dropped')),
        ('WA', _('Want to play')),
    )
    user = models.ForeignKey(User)
    game = models.ForeignKey(Game)
    status = models.CharField(_('Status'), max_length=2,
                              choices=STATUS_CHOICES)

在我看来,我正在按用户过滤条目,如下所示:

class GameListByUserView(ListView):
    model = ListEntry
    template_name = 'game_list_by_user.html'

    def get_queryset(self):
        self.user_profile = get_object_or_404(User, username=self.kwargs['slug'])
        return ListEntry.objects.filter(user=self.user_profile)

    def get_context_data(self, **kwargs):
        context = super(GameListByUserView, self).get_context_data(**kwargs)
        context['user_profile'] = self.user_profile
        return context

我现在要做的是ListEntry.objects.filter(user=self.user_profile)根据status属性将此查询 () 拆分为子组,因此呈现的模板如下所示:

UserFoo's list
=========================

Playing

Game 1
Game 2
Game 3


Completed

Game 4
Game 5
Game 6

我知道我可以做类似的事情:

q = ListEntry.objects.filter(user=self.user_profile)
games_dict = {}
games_dict['playing'] = q.filter(status='PL')
games_dict['completed'] = q.filter(status='CO')

依此类推,并遍历模板中的键。或者(在模板中):

{% for s in status_choices %}
  {% for entry in object_list %}
    {% if entry.status == s %}
      Render things
    {% endif %}
  {% endfor %}
{% endfor %}

但是,是否有一种更好、优化的方法来做到这一点,而无需每次按状态获取子查询时都访问数据库,并且无需多次迭代对象列表?

4

1 回答 1

3

您正在寻找regroup过滤器

{% regroup object_list by status as games_list %}

<ul>
{% for game in games_list %}
    <li>{{ game.grouper }}
    <ul>
        {% for item in game.list %}
          <li>{{ item}}</li>
        {% endfor %}
    </ul>
    </li>
{% endfor %}
</ul>

您可能需要自定义元素的渲染方式,但我会让您自己弄清楚。

于 2014-09-17T21:09:11.663 回答