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.

+1


source to share


1 answer


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

you need to add context processors,
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
)

      

+2


source







All Articles