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.
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.
精彩评论