Tengo una página de administración de Django para un modelo con un solo modelo en línea. Cuando el modelo en línea tiene muchos elementos (como 75), la página se carga muy lentamente (del orden de 30 segundos). Esto es cierto incluso si excluyo todos los campos en el modelo en línea, haciendo que solo represente el nombre. Eliminar el modelo en línea hace que la página se cargue muy rápido (en segundos).
¿Cómo puedo hacer que esta página cargue más rápido?
Hay dos cosas que puede hacer para acelerar la carga de esta página.
DEBUG = False . La razón por la que la página se carga lentamente es que el administrador de Django está representando una subplantilla para cada instancia del modelo en línea. Con 75 instancias del modelo en línea, está representando 75 plantillas adicionales, incluso si tienen un contenido mínimo. Si bien la representación de una plantilla suele ser muy rápida, si tiene DEBUG = True , incurre en una sobrecarga adicional para cada plantilla que representa porque Django está inyectando contexto adicional para su página de error de modo de depuración (esto es aproximadamente 0,4 segundos por plantilla en mi sistema) . Esta sobrecarga adicional normalmente no se nota porque normalmente solo está procesando un puñado de plantillas para una sola página. Sin embargo, cuando procesa 75 plantillas, esto se suma a un retraso notable (75 * 0,4 segundos = 30 segundos).
Al menos a partir de Django 1.10, el modelo en línea realizará las consultas de base de datos necesarias para representarlo para cada instancia del modelo en línea. Si su modelo en línea tiene claves externas en el modelo en línea, esto puede ser bastante ineficiente si tiene una conexión de base de datos lenta. La técnica es ejecutar consultas de base de datos para las opciones de estas claves externas cuando inicializa la instancia de la clase en línea (usando get_formsets_with_inlines ), y luego reemplaza las opciones de estos campos en línea con los valores almacenados en caché para evitar repetir esta consulta de base de datos ( usando 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), inlineMira mi solución aquí: https://stackoverflow.com/a/51391915/1496567
Mis clases de administración se ven así:
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, )