在我的管理页面中,我有带有 OrderItem 模型的 TabularInline 的 Order 模型
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')
三个外键:1.Order 2.Product 3.Variant
一对多:product_add_ons
与 select_related/prefetch 相关,仅减少了 19 个查询,但是,发现了 35 个重复/相似的查询。
请注意以下事实:
- ALL 重复查询份额
NO SCROLL CURSOR WITH HOLD FOR SELECT
删除内联会删除所有重复的查询。
删除任何 FK 或 ManyToMany 也大大减少了重复查询
删除 select_related/prefetch_related 将导致
70 queries including 55 similar and 35 duplicates
知道为什么会这样吗?
最佳答案
经过多次搜索和几次失败尝试后确定。
我最终通过使用模型表单并将其添加到管理内联
成功地删除了所有重复/相似的查询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')
关于Django Admin 内联重复查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66108310/