Reputation: 238
In my Admin page I have Order model with TabularInline of OrderItem model
class OrderItemStackAdmin(admin.TabularInline):
model = OrderItem
extra = 0
fieldsets = (
(_('Product'), {
'fields': ('product', 'variant')
}), (_('Add-Ons'), {
'fields': ('product_add_ons', 'add_ons_note')
}), (_('Price'), {
'fields': ('quantity', 'product_price', 'add_ons_total_price')
}), (_('Discount'), {
'fields': ('discount',)
})
)
def get_queryset(self, request):
qs = super().get_queryset(request)
return qs.select_related(
"customer_order",
"product",
"variant"
).prefetch_related('product_add_ons')
Three foreign keys: 1.Order 2.Product 3.Variant
One ManyToMany: product_add_ons
With select_related/prefetch related, only 19 queries reduced, however, 35 duplicate/similar queries are found.
Please note the below facts:
NO SCROLL CURSOR WITH HOLD FOR SELECT
Removing the inline removes all duplicated queries.
Removing any FK or ManyToMany also greatly reduce duplicated queries
Removing select_related/prefetch_related will result in
70 queries including 55 similar and 35 duplicates
Any ideas why this is happening?
Upvotes: 3
Views: 1922
Reputation: 238
Ok after many searches and several fail tries.
I finally managed to remove all duplicated/similar queries by using Model form and adding it to admin inline
class OrderItemForm(forms.ModelForm):
""" OrderItem Model Form """
products_choices = [('', '---------')]
for item in Product.objects.values('pk', 'name', 'arabic_name'):
products_choices.append(
(item['pk'], f"{item['arabic_name']}-{item['name']}"))
product = forms.ChoiceField(required=True,
choices=products_choices)
variants_choices = [('', '---------')]
variants_choices.extend(Variants.objects.values_list('pk', 'name'))
variant = forms.ChoiceField(required=False,
choices=variants_choices)
class OrderItemStackAdmin(admin.TabularInline):
""" Stacked Order Items """
model = OrderItem
form = OrderItemForm
autocomplete_fields = ['product_add_ons']
extra = 0
fieldsets = (
(_('Product'), {
'fields': ('product', 'variant')
}), (_('Add-Ons'), {
'fields': ('product_add_ons', 'add_ons_note')
}), (_('Price'), {
'fields': ('quantity', 'product_price', 'add_ons_total_price')
}), (_('Discount'), {
'fields': ('discount',)
})
)
def get_queryset(self, request):
qs = super().get_queryset(request)
return qs.prefetch_related('product_add_ons')
Upvotes: 2