Hello people :)

I am struggling with optimizing an admin with inlines which causes too
many database requests.

My model structure is like this:

    class ExampleA(models.Model):
        ...
   
    class ExampleB(models.Model):
        aexample = models.ForeignKey('ExampleA', related_name='bexamples')
        cexample = models.ForeignKey('ExampleC')
        dexample = models.ForeignKey('ExampleD')
        eexample = models.ForeignKey('ExampleE')
        ...

    class ExampleC(models.Model):
        ...
   
    class ExampleD(models.Model):
        ...
   
    class ExampleE(models.Model):
        ...

The admin classes:

    class ExampleBInline(admin.StackedInline):
        model = ExampleB
        extra = 0

    class ExampleAAdmin(admin.ModelAdmin):
        inlines = [ExampleBInline]

    admin.site.register(ExampleA, ExampleAAdmin)

As I can see with django-debug-toolbar, when rendering the admin
template for the inline formset with the forms for ExampleB objects, a
new db request is sent to db server for each related field of each
ExampleB object. Particularly, I am seeing a lot of queries like these:

    SELECT ••• FROM `examplec` WHERE `examplec`.`id` = 1 LIMIT 21
    SELECT ••• FROM `examplee` WHERE `examplee`.`id` = 2 LIMIT 21
    SELECT ••• FROM `examplec` WHERE `examplec`.`id` = 2 LIMIT 21
    SELECT ••• FROM `exampled` WHERE `exampled`.`id` = 2 LIMIT 21
    SELECT ••• FROM `examplee` WHERE `examplee`.`id` = 3 LIMIT 21

The template context is this (I am using grappelli):
   
                    21        {% if field.is_readonly %}
                    22            <div class="grp-readonly">{{
field.contents|linebreaksbr }}</div>
                    23        {% else %}
the marked line =>  24            {{ field.field }}
                    25        {% endif %}
                    26    {% endif %}
                    27        {% if line.fields|length_is:'1' %}{{
line.errors }}{% endif %}


I have tried the following optimizations:

First try:

    class ExampleAAdmin(admin.ModelAdmin):
        inlines = [ExampleBInline]

        def get_queryset(self, request):
            qs = super(ExampleAAdmin, self).get_queryset(request)
            return qs.prefetch_related('bexamples',
'bexamples__cexample', 'bexamples__dexample', 'bexamples__example')

Second try:

    class ExampleBInline(admin.StackedInline):
        model = ExampleB
        extra = 0
      
        def get_queryset(self, request):
            qs = super(ExampleInline, self).get_queryset(request)
            return qs.select_related('cexample', 'dexample', 'eexample')

Third try:

    class BaseExampleBFormSet(BaseInlineFormSet):
        def __init__(self, *args, **kwargs):
            super(BaseExampleBFormSet, self).__init__(*args, **kwargs)
            qs = self.queryset
            self.queryset = qs.select_related('cexample', 'dexample',
'eexample')

    ExampleBFormSet = inlineformset_factory(ExampleA, ExampleB,
formset=BaseExampleBFormSet)

    class ExampleBInline(admin.StackedInline):
        model = ExampleB
        extra = 0
        formset = ExampleBFormSet

Unfortunately, none of the above works.

So, I would be really grateful if anyone could help on this by giving
any hint or pointing out what could be possibly missing. Or, could I
have hit a restriction of django admin's internals?

Thank you in advance,

Petros

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/5499A2A1.3040403%40yahoo.gr.
For more options, visit https://groups.google.com/d/optout.

Reply via email to