urls template python django django-urls

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 )