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.