Django apartment building
T; dr: Is there a way to override the default behavior reverse
?
In my django project I have many urls like
url(r'^\w+/company/', include("company.urls", namespace="company")),
Which allows for URLs like
.../companyA/company/
.../companyB/company/
So that I can then use specialized middleware to modify the request to include some specific data depending on which company is using my site
Everything works fine, except that django tries to decrypt the full path with reverse
and {% url .. %}
...
Seems to return /x/company/
as default match for regex. since the method django.utils.regex_helper
next_char
has an escaping mapping for \w
to display inx
A tag url
that I was able to override to replace /x/
with the correct company name, and I wonder if there is a similar thing I can do to override reverse
in the same way, or is there anything else I can do to fix this problem?
I used to use
url(r'^(?P<company_name>\w+)/company/', include("company.urls", namespace="company"))
But this meant that I had to include the parameter in all kinds
def view(request, company_name):
...
Also include it in all my other calls to the view (i.e. from {% url %}
) that I'm trying to avoid.
source to share
For ease of use, Django packages are compiled as a page full of all possible existing django packages that can do this. However below is my own simple implementation
I changed my nginx proxy config to use the following
server_name ~(?<short_url>\w+)\.domainurl\.com$;
... stuff related to static files here
location / {
proxy_set_header X-CustomUrl $short_url;
.... other proxy settings
}
What this means is to create a variable inside the request header, which can then be used in Django. I then used this variable as part of a custom middleware to extend the request with a reference to the model so that it can be used anywhere.
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
Examples:
www.companya.domainurl.com # short_url is companya
test.domainurl.com # short_url is test
To use this in a template, in 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
)
source to share