python - template - django views
Django multi tenancy (1)
Tl;
dr: ¿Hay alguna forma de anular el comportamiento predeterminado de
reverse
?
En mi proyecto django tengo muchas URL como
url(r''^/w+/company/'', include("company.urls", namespace="company")),
Lo que permite URL como
.../companyA/company/
.../companyB/company/
Para que luego pueda usar un middleware personalizado para modificar la solicitud para incluir algunos detalles específicos basados en qué compañía está usando mi sitio
Todo esto funciona bien, excepto cuando django está tratando de descifrar la ruta completa con
reverse
y
{% url .. %}
...
Parece estar devolviendo
/x/company/
como una coincidencia predeterminada para la expresión regular.
dado que el método
next_char
tiene una asignación de escape para
/w
para asignar a
x
La etiqueta de
url
que he podido
override
para reemplazar
/x/
con el nombre correcto de la compañía y me pregunto si hay algo similar que pueda hacer para anular la
reverse
de la misma manera, o cualquier otra cosa que pueda hacer para resolver ¿este problema?
Anteriormente estaba usando
url(r''^(?P<company_name>/w+)/company/'', include("company.urls", namespace="company"))
Pero esto significaba que tenía que incluir un parámetro en cada vista
def view(request, company_name):
...
Además de incluirlo en todas mis otras llamadas a la vista (es decir, con el
{% url %}
) que estoy tratando de evitar.
Para facilitar su uso, los paquetes de Django compilan una this que pueden lograr esto. Sin embargo, a continuación se muestra mi propia implementación simple
Modifiqué mi configuración de proxy nginx para usar lo siguiente
server_name ~(?<short_url>/w+)/.domainurl/.com$;
... stuff related to static files here
location / {
proxy_set_header X-CustomUrl $short_url;
.... other proxy settings
}
Lo que esto hace es crear una variable dentro de un encabezado de solicitud que luego se puede usar dentro de Django. Luego utilicé esta variable dentro de un middleware personalizado para extender una solicitud con una referencia al modelo que permite su uso en cualquier lugar.
class CompanyMiddleware(object):
def process_request(self, request):
if settings.DEBUG:
request.company = CompanyClass.objects.get(id=1)
return None
short_url = request.META.get("HTTP_X_CUSTOMURL")
try:
company = CompanyClass.objects.get(short_url=short_url)
except Model.DoesNotExist:
return HttpResponseBadRequest(''Company not found'')
request.company = company
return None
Ejemplos:
www.companya.domainurl.com # short_url is companya
test.domainurl.com # short_url is test
Para usar esto dentro de una plantilla, los procesadores de contexto deben agregarse a
settings.py
TEMPLATE_CONTEXT_PROCESSORS = (
"django.contrib.auth.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
''django.core.context_processors.request'' # This one in particular
)