Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

126
Visualizações
Django Admin Page with Inline Model Loads Very Slowly

I have a Django admin page for a model with a single inline model. When the inline model has many items (like 75), the page loads very slowly (on the order of 30 seconds). This is true even if I exclude all of the fields on the inline model, having it just render the name. Removing the inline model causes the page to load very quickly (in seconds).

How can I have this page load faster?

about 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

There are two things you can do to speed up the loading of this page.

  1. Set DEBUG = False.
  2. Cache the database queries used in the rendering of the inline model.

DEBUG = False

The reason that the page loads slowly is that the Django admin is rendering a subtemplate for every instance of the inline model. With 75 instances of the inline model, you are rendering 75 extra templates, even if there is minimal content in them. While rendering a template is normally very fast, if you have DEBUG = True, you incur extra overhead for every template you render because Django is injecting extra context for its debug-mode error page (this is about 0.4 seconds per template on my system). This extra overhead is normally not noticeable because you are normally only rendering a handful of templates for a single page. When you render 75 templates, however, this adds up to a noticeable delay (75 * 0.4 seconds = 30 seconds).


Caching database queries

At least as of Django 1.10, the inline model will make any necessary database queries to render it for each instance of the inline model. If your inline model has any foreign keys on the inline model, this can pretty inefficient if you have a slow database connection. The technique is to run database queries for the choices of these foreign keys when you initialize the instance of the inline class (using get_formsets_with_inlines), and then replace the choices of these fields on the inline with the cached values to prevent repeating this database query (using formfield_for_foreignkey).

class Manufacturer(models.Model):
    ...

class OperatingSystem(models.Model):
    ...

class Computer(models.Model):
    manufacturer = models.ForeignKey(Manufarturer)
    owner = models.ForeignKey(User)
    operating_system = models.ForeignKey(OperatingSystem)
    ...


class ComputerAdmin(admin.StackedInline):
    model = Computer

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        field = super(ComputerAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
        if db_field.name == "owner" and hasattr(self, "cached_owners"):
            field.choices = self.cached_owners
        elif db_field.name == "manufacturer" and hasattr(self, "cached_manufacturers"):
            field.choices = self.cached_manufacturers
        elif db_field.name == "operating_system" and hasattr(self, "cached_operating_systems"):
            field.choices = self.cached_operating_systems
        return field


class ManufacturerAdmin(admin.ModelAdmin):
    inlines = (ComputerAdmin,)

    def get_formsets_with_inlines(self, request, obj=None):
        for inline in self.get_inline_instances(request, obj):
            inline.cached_owners = [(i.pk, str(i)) for i in User.objects.all()]
            inline.cached_manufacturers = [(i.pk, str(i)) for i in Manufacturer.objects.all()]
            inline.cached_operating_systems = [(i.pk, str(i)) for i in OperatingSystem.objects.all()]
            yield inline.get_formset(request, obj), inline
about 4 years ago · Santiago Trujillo Relatório

0

Check out my solution here: https://stackoverflow.com/a/51391915/1496567

My admin classes look like follows:

class ItemBazarInlineAdmin(AdminInlineWithSelectRelated):
    model = ItemBazar

    list_select_related = (
        'alumno_item__alumno__estudiante__profile',
        'alumno_item__item__anio_lectivo',
        'comprobante__forma_pago',
    )


class ComprobanteAdmin(AdminWithSelectRelated):
    list_display = ('__str__', 'total', 'estado', 'fecha_generado', 'forma_pago', 'tipo', )
    list_filter = ('estado', 'forma_pago', )

    list_select_related = ('forma_pago', )
    inlines = (ItemServicioInlineAdmin, )
about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda