通用视图DetailView上的Django prefetch_related

时间:2012-10-26 11:41:28

标签: python django orm

我有这个mixin在视图上应用prefetch_related。这是我应该处理的查询集:

MyMode.objects.all().prefetch_related('projects')

使用这些模型:

class Workspace():
 name = models.CharField(max_length=255)
class Project():
 name = models.CharField(max_length=255)
 workspace = models.Foreignkey(Workspace)

我创建了这个mixin:

class PrefetchRelatedMixin(object):
    prefetch_related = None

    def get_queryset(self):
        if self.prefetch_related is None:
            raise ImproperlyConfigured(u'%(cls)s is missing the prefetch_related'
                "property. This must be a tuple or list." % {
                'cls': self.__class__.__name__})

        if not isinstance(self.prefetch_related, (tuple, list)):
            raise ImproperlyConfigured(u"%(cls)s's select_related property "
                "must be a tuple or list." % {"cls": self.__class__.__name__})

        queryset = super(PrefetchRelatedMixin, self).get_queryset()

        return queryset.prefetch_related(
            ", ".join(self.prefetch_related)
        )

在视图中调用如下:

class WorkspaceView(DetailView):
    prefetch_related = ['projects']
    model = Workspace

    def get_queryset(self):
        return super(WorkspaceView, self).get_queryset()

但是,当我尝试迭代模板中的相关对象时:

{% for p in object.projects %}
    <li>{{ p.name }}</li>
{% empty %}
    <li>No Projects in this Workspace</li>
{% endfor %}

我收到此错误:

'RelatedManager' object is not iterable

mixin中是否有某些东西改变了对象以便它返回一个RelatedManager?

提前致谢!

2 个答案:

答案 0 :(得分:2)

@danihp拥有它:你需要.all

此处也有错误:

return queryset.prefetch_related(
            ", ".join(self.prefetch_related)
        )

应该阅读

return queryset.prefetch_related(*self.prefetch_related)

prefetch_related接受多个字符串参数,而不是一个以逗号分隔的字符串。

答案 1 :(得分:1)

prefetch_related是RelatedManager,您应该执行获取结果的方法:

在docs示例中:

>>> pizzas = Pizza.objects.prefetch_related('toppings')
>>> [list(pizza.toppings.filter(spicy=True)) for pizza in pizzas]

针对您的情况:

{% for p in object.projects.all %}
相关问题