Reputation: 2589
Im trying to do a prefetch within a prefetch in django but am getting the below error:
First argument to get_object_or_404() must be a Model, Manager, or QuerySet, not 'QuerySet'.
this is the query:
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
)
if I remove the below, the query works successfully, so I know its related to chaining the prefetches im just not sure why or how to rectify this?
.prefetch_related('servicecontacts_set')
EDIT:
tried the below
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')
error:
AttributeError: Cannot find 'servicecontacts_set' on Circuits object, 'servicecontacts_set' is an invalid parameter to prefetch_related()
service contacts is a model linked to circuits, service contacts is not linked to site data if that helps?
>>> 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>}
>>>
Upvotes: 0
Views: 648
Reputation: 1187
Well, prefetech_related is used for preventing duplicate queries and every prefetch_related arg produces extra query anyway. It follows that the using prefetch_related for a single object has no sense. So, just put it like this:
site.sitesubnets_set.prefetch_related(Prefetch(...)).filter(...)
site.circuits_set.prefetch_related(Prefetch(...)).filter(...)
It won't produce any excessive queries
Upvotes: 2