I have a BaseModel(models.Model), and ExtendedModelA(BaseModel) and ExtendedModelB(BaseModel). ExtendedModelA and ExtendedModelB both have foreign key fields to other models. Their unicode methods return a field from this foreign key related model.
I have a dropdown menu which I want to populate with BaseModel objects (which naturally includes ExtendedModelA and ExtendedModelB objects). To do this I need a queryset which will get all extended objects (type A and B) and their related objects.
I have a merged queryset:
queryset = BaseModel.objects.filter(type=1).select_related('extendedmodela') | BaseModel.objects.filter(type=2).select_related('extendedmodelb')
The trouble is that the unicode representation of the BaseModel is presented in the dropdown. If I add a unicode method to the BaseModel class which has conditions:
if hasattr(self, extendedmodela):
return self.extendedmodela.__unicode__()
else:
return self.extendedmodelb.__unicode__()
This results in querying the database for each object.
Anyone any ideas about how to get myself out of this mess?
Essentially I need to formulate a queryset which will get all BaseModel objects efficiently, and when they're displaying in the dropdown their unicode methods for their respective extended classes (which print fields from a foreign key field object) dont hammer the database. I have a few thousand objects so the database takes a hit.
Cheers,
Dean
You're using select_related
, which is good. I think you can optimize your query by using a Q
, which essentially lets you filter for either type 1 or type 2 in this case.
from django.db.models import Q
BaseModel.objects.filter(Q(type=1) | Q(type=2)).select_related('extendedmodela').select_related('extendedmodelb')
EDIT
You can use the double-underscore notation to access deeper fields that are on related models. eg.
.select_related('extendedmodela', 'extendedmodela__fkfieldname')
Why not just pass a mixed bag to the dropdown. This is no longer a QuerySet
, but the dropdown won't mind:
qs = list(ExtendedModelA.objects.select_related('whatever_fk_needed')) +\
list(ExtendedModelB.objects.select_related('whatever_fk_needed'))
Whatever instance is selected, will have the same id
as its BaseModel
instance.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.