如何在基于类的View上使fetch_related工作?

时间:2015-02-26 03:15:41

标签: django django-class-based-views

我非常喜欢CBV方法但似乎无法在这种情况下使其工作。 TeamPerson模型通过players模型通过Player M2M关系进行连接。

class Person(Model):
    last_name = CharField(max_length=30)
    ...
class Team(Model):
    players = ManyToManyField(Person, through='Player')
    ...
class Player(Model):
    person = ForeignKey(Person)
    team = ForeignKey(Team)
    date_joined = DateField()
    ...

在团队详细信息页面上使用姓名和date_joined的团队名单为每个玩家提供一个查询,因此我预取了玩家数据:

def team_detail_view(request, pk=None):
    ...
    team = Team.objects.get(pk=pk)
    roster = team.player_set.all().prefetch_related('person')
    return render_to_response('team_detail.html', 
        {'object': team, 'roster': roster}, ...)

如何让CBV使用prefetch_related?我在django-braces中找到PrefetchRelatedMixin,但是当我做

class TeamDetailView(PrefetchRelatedMixin, DetailView):
    prefetch_related = [u'players']
    model = Team

这仍然为模板中的每个玩家提供单独的查询

{% for player in object.player_set %}
<tr><td>{{ player.person.last_name }}</td><td>{{ player.date_joined }}</td></tr>
{% endfor %}

似乎需要的是在团队模型的M2M字段上调用prefetch_related的方法,而不是团队本身。可以用CBV完成吗?

3 个答案:

答案 0 :(得分:0)

您是否尝试重写get_queryset()?

class TeamDetailView(DetailView):
    ...

    def get_queryset(self):
        return self.queryset.prefetch_related('players').all()

答案 1 :(得分:0)

DetailView在self.get()上运行而不是self.get_queryset(),其中你的Mixin重载。您必须修改PrefetchRelatedMixin以支持get()上的prefetch_related属性。

答案 2 :(得分:0)

原来那个

class TeamDetailView(PrefetchRelatedMixin, DetailView):
    prefetch_related = ['player_set__person']
    model = Team

可以解决问题,但我并不完全确定它的机制。