django-nested-admin
django-nested-admin copied to clipboard
Bad performance with nested polymorphic models
Hi! First of all, I have to say that I am really happy I found this plugin!
I used a polymorphic model that related to another polymorphic model. I total I have 5 polymorphic types on the first level and 3 on the second one. It produces about 26 000 lines of HTML code and takes 5 seconds to render it.
There is a pretty simple solution to reduce the rendering time by using caching:
In templates/nesting/admin/inlines/polymorphic_stacked.html change this:
{% if inline_admin_form.form.inlines %}
{% for nested in inline_admin_form.form.inlines %}
{% include nested.opts.template with inline_admin_formset=nested %}
{% endfor %}
{% endif %}
to this:
{% if inline_admin_form.is_empty and inline_admin_form.form.inlines %}
{% with inline_admin_formset.opts|to_class_name as formset_class_name %}
{% cache 600 repeated-nested-template formset_class_name %}
{% if inline_admin_form.form.inlines %}
{% for nested in inline_admin_form.form.inlines %}
{% include nested.opts.template with inline_admin_formset=nested %}
{% endfor %}
{% endif %}
{% endcache %}
{% endwith %}
{% else %}
{% if inline_admin_form.form.inlines %}
{% for nested in inline_admin_form.form.inlines %}
{% include nested.opts.template with inline_admin_formset=nested %}
{% endfor %}
{% endif %}
{% endif %}
and this this to the top of the file:
{% load cache %}
{% load adminextras %}
templatetags/adminextras.py:
from django import template
register = template.Library()
@register.filter
def to_class_name(value):
return value.__class__.__name__
It reduces rendering time from 5 to 2 seconds.
Currently, I don't have enough time to prepare PR with tests but hope this snippet will be helpful for someone.
This is a brilliant idea. I think I'll probably put it behind a setting and disable it by default, but this will help us as well with performance.
This turns out to be not as straightforward as I would have hoped. There are more variables involved than just formset_class_name
that would need to vary the cache.