预取中的django预取 - 必须是Model,Manager或QuerySet,而不是' QuerySet'

时间:2018-01-11 09:15:24

标签: django

我试图在django中的预取中进行预取但是得到以下错误:

First argument to get_object_or_404() must be a Model, Manager, or QuerySet, not 'QuerySet'.

这是查询:

site = get_object_or_404(SiteData.objects.prefetch_related(
                                Prefetch(
                                    'sitesubnets_set',
                                    queryset=SiteSubnets.objects.filter(site_ip=True),
                                ),
                                Prefetch(
                                    'circuits_set',
                                    queryset=Circuits.objects.exclude(decommissioned=True).prefetch_related('servicecontacts_set'),
                                )
                            ),
                        pk=site_id 
                        )

如果删除下面的内容,查询会成功运行,所以我知道它与链接预取相关,我不确定为什么或如何纠正这个问题?

.prefetch_related('servicecontacts_set')

编辑:

尝试了下面的

site = get_object_or_404(SiteData.objects.prefetch_related(
                                Prefetch(
                                    'sitesubnets_set',
                                    queryset=SiteSubnets.objects.filter(site_ip=True),
                                ),
                                Prefetch(
                                    'circuits_set',
                                    queryset=Circuits.objects.exclude(decommissioned=True),
                                )
                            ),
                        pk=site_id 
                        )         
site.circuits_set.prefetch_related('servicecontacts_set')

错误:

AttributeError: Cannot find 'servicecontacts_set' on Circuits object, 'servicecontacts_set' is an invalid parameter to prefetch_related()

服务联系人是一个链接到电路的模型,如果有帮助,服务联系人没有链接到网站数据?

>>> vars(site.circuits_set.all()[0])
{'_state': <django.db.models.base.ModelState object at 0x7fa05dcf2978>, 'id': 5, 'site_data_id': 7, 'order_no': 'N/A', 'expected_install_date': datetime.date(2016, 10, 19), 'install_date': datetime.date(2016, 5, 26), 'service_contacts_id': 10, 'decommissioned': False, '_site_data_cache': <SiteData: London>}
>>>

1 个答案:

答案 0 :(得分:2)

好吧,prefetech_related用于防止重复查询,并且每个prefetch_related arg都会产生额外的查询。因此,对单个对象使用prefetch_related没有任何意义。所以,就这样说:

create table nzhang_part(a string) partitioned by (ds string, dept int);
insert overwrite nzhang_part (dept=1)
  select a, ds, dept from T
  where dept=1 and ds is not null;

它不会产生任何过多的查询