you tutorial template tag register forget expected examples endblock did bootstrap django architecture multi-tenant

tutorial - arquitectura óptima para aplicación multiusuario en django



static expected endblock did you forget to register or load this tag (3)

Aquí hay algunos consejos para discusiones relacionadas:

He estado reflexionando sobre la forma correcta / óptima para crear una aplicación de multiempresa basada en Django.

Alguna explicación:

  • La aplicación puede ser utilizada por varios inquilinos (inquilino1, inquilino2, ...,).

  • Todos los datos individuales del inquilino deben estar protegidos contra el acceso de otros inquilinos (y sus usuarios).

  • Opcionalmente, los inquilinos pueden crear campos personalizados adicionales para los objetos de la aplicación.

  • Por supuesto, el hardware subyacente limita el número de inquilinos en un "sistema".

1) Separar cada inquilino por ej., Subdominio y usar bases de datos específicas del inquilino en la capa subyacente

2) Usar alguna identificación de inquilino en el modelo para separar los datos de inquilino en la base de datos

Estoy pensando en los procesos de implementación, el rendimiento de las partes del sistema (servidor (s) web, servidor (s) de base de datos, nodo (s) de trabajo, ...)

¿Cuál sería la mejor configuración? ¿Dónde están los pro y los con''s?

¿Qué piensas?


Creamos una platform multiempresa con la siguiente arquitectura. Espero que puedas encontrar algunos consejos útiles.

  • Cada inquilino obtiene un subdominio (t1.example.com)
  • El uso de url reescribiendo las solicitudes para la aplicación Django se reescribe en algo como example.com/t1
  • Todas las definiciones de url tienen el prefijo algo como (r''^(?P<tenant_id>[/w/-]+)
  • Un middleware procesa y consume el tenant_id y lo agrega a la solicitud (por ejemplo, request.tenant = ''t1'')
  • Ahora tiene el inquilino actual disponible en cada vista sin especificar el argumento tenant_id cada vista
  • En algunos casos, no tiene la solicitud disponible. Resolví este problema vinculando el tenant_id con el subproceso actual (similar al idioma actual usando threading.local )
  • Cree decoradores (p. Ej., Un login_required consciente del inquilino), middlewares o fábricas para proteger las vistas y seleccionar los modelos correctos
  • En cuanto a las bases de datos utilicé dos escenarios diferentes:
    • Configure múltiples bases de datos y configure un routing acuerdo con el inquilino actual. Usé esto primero, pero cambié a una base de datos después de aproximadamente un año. Las razones fueron las siguientes:
      • No necesitamos una solución de alta seguridad para separar los datos
      • Los diferentes inquilinos usaron casi todos los mismos modelos
      • Tuvimos que gestionar muchas bases de datos (y no creamos un proceso fácil de actualización / migración)
    • Utilice una base de datos con algunas tablas de asignación simples para, por ejemplo, usuarios y diferentes modelos. Para agregar campos modelo adicionales e inquilinos usamos herencia modelo .

Respecto al medio ambiente utilizamos la siguiente configuración:

Desde mi punto de vista, esta configuración tiene los siguientes pro y contras:

Pro:

  • Una instancia de aplicación que conoce al inquilino actual
  • La mayoría de las partes del proyecto no tienen que preocuparse por los problemas específicos del inquilino
  • Solución fácil para compartir entidades entre todos los inquilinos (por ejemplo, mensajes)

Contra:

  • Una base de datos bastante grande
  • Algunas tablas muy similares debido a la herencia del modelo
  • No asegurado en la capa de la base de datos

Por supuesto, la mejor arquitectura depende en gran medida de sus requisitos como el número de inquilinos, el delta de sus modelos, los requisitos de seguridad, etc.

Actualización : cuando revisamos nuestra arquitectura, sugiero no reescribir la URL como se indica en el punto 2-3. Creo que una solución mejor es poner el tenant_id como un encabezado de solicitud y extraer (punto 4) el tenant_id de la solicitud con algo como request.META.get(''TENANT_ID'', None) . De esta forma obtienes URLs neutrales y es mucho más fácil usar las funciones integradas de Django (por ejemplo, {% url ...%} o reverse() ) o aplicaciones externas.