Yousef Alm
Yousef Alm

Reputation: 238

Django Admin Inline duplicated queries

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.

Screenshot

Please note the below facts:

  1. ALL duplicated queries share

NO SCROLL CURSOR WITH HOLD FOR SELECT

  1. Removing the inline removes all duplicated queries.

  2. Removing any FK or ManyToMany also greatly reduce duplicated queries

  3. 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

Answers (1)

Yousef Alm
Yousef Alm

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

Related Questions