Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Safe to modify settings.SITE_ID from middleware in Django?

I have modified the multihost.py middleware I found at http://effbot.org/zone/django-multihost.htm to set the settings.SITE_ID dynamically, but have some concerns that I may have just left the reservation.

Most examples I have found for multiple domain hosting have been setup with multiple settings.py files hardcoded to their respective SITE_IDs.

Have I created a fix with a fatal flaw here? Will changing this value dynamically bite me on the a**.

from django.conf import settings
from django.contrib.sites.models import Site

class MultiHostMiddleware:

    def process_request(self, request):
        try:
            host_raw = request.META["HTTP_HOST"]
            colon = host_raw.find(':')
            if colon > -1:
                host = host_raw[0:colon]
            else:
                host = host_raw

            s = Site.objects.get(domain=host)
            if s:
                settings.SITE_ID = s.id

        except KeyError:
            pass # use default urlconf (settings.ROOT_URLCONF)

For the curious this is up and running so far, but has not stood up to actual traffic.

like image 846
Ryan Townshend Avatar asked Aug 12 '10 01:08

Ryan Townshend


People also ask

What is the purpose of middleware in Django?

Middleware is a framework of hooks into Django's request/response processing. It's a light, low-level “plugin” system for globally altering Django's input or output. Each middleware component is responsible for doing some specific function.

What is Django middleware security SecurityMiddleware?

The django. middleware. security. SecurityMiddleware provides several security enhancements to the request/response cycle. Each one can be independently enabled or disabled with a setting.

Is middleware a decorator?

Middleware and decorators are similar and can do the same job. They provide a means of inserting intermediary effects either before or after other effects downstream in the chain/stack.


1 Answers

The short, official answer is you're not supposed to do this, though the docs don't really explain why not.

If you're using a threaded server, I'd be concerned about a race condition. This should be quite simple to test; just put a call to sleep() in one view, then return an HttpResponse with the name of the current site. While the first view is sleeping, hit a different view on a different domain.

If you use prefork, I don't imagine that this would cause any problems. I've used this approach with matplotlib, since it's easiest to set graph properties by changing global configuration with matplotlib.rcParams.update(). I use prefork fcgi, so I can safely assume that each request has the whole process to itself (folks, please correct me if I'm wrong).

Edit: I think you can do what you want using RequestSite by disabling the sites application. James Bennett's django-registration, for example, instantiates a RequestSite object in that case, which extracts the hostname from the request object.

like image 125
Aryeh Leib Taurog Avatar answered Oct 10 '22 08:10

Aryeh Leib Taurog