使用带有prefetch_related的queryset manager

时间:2016-09-05 08:40:03

标签: django

我成功地使用这种出色的技术来保持我的代码DRY在查询集中封装ORM关系,以便视图中的代码很简单并且不包含外键依赖性。但这次我面临以下问题,最好用代码描述:

查看:

vendors_qs = vendors_qs.select_related().prefetch_related('agreement_vendors')

模型 class AgreementVendorsQuerySet(models.query.QuerySet):

def some_filter1(self, option):
    result = self.filter(.....)
    return result

def some_filter2(self, option):
    result = self.filter(.....)
    return result

一个模板:

{% for vendor in vendors_qs %}
    <tr>
        ...
        <td>
           {% for vend_agr in vendor.agreement_vendors.all %}
               {{vend_agr.serial_number}}
           {% endfor %}
        <td>
    </tr>
 {% endfor %}

问题是,如果some_filter1被提取为prefetch_related关系,我将如何以及在何处将if (condition_1) vendors_qs = vendors_qs.filter1() if (condition_2) vendors_qs = vendors_qs.filter2() 应用于供应商协议。我是否必须以某种方式或在视图本身中应用模板中的过滤器? 如果我没有明确提出问题,我会问你的问题进一步澄清......

更新: 安娜的asnwer看起来非常像真相,但一个细节仍然不清楚。如果我想根据if条件应用多个过滤器该怎么办?例如,如果过滤器适用于供应商,那么代码看起来就像:

order by

1 个答案:

答案 0 :(得分:2)

如果我清楚地理解你的问题,你需要这样的事情

    vendors_qs = vendors_qs.prefetch_related(models.Prefetch('agreement_vendors', queryset=some_filter, to_attr='agreement_vendors_list'))

然后在模板中,您可以将其称为{% for vend_agr in vendor.agreement_vendors_list %}