On 31/01/12 11:45, akaariai wrote: > On Jan 31, 12:01 am, Tom Eastman <t...@catalyst.net.nz> wrote: >> Hey guys, >> >> I'm writing a django project that will require me to route queries to >> certain large databases based on who the logged in user is. >> >> So all the tables for django.contrib.auth and session and stuff will be >> in the 'central' database, as well as a table that maps users to which >> database they need to use for the main app. >> >> Can you help me come up with a way of routing database queries this way >> using a Django database router? >> >> At the start of the view could I take the logged in user from >> request.user or wherever it is, and some how provide that variable to my >> database router for the rest of the request? >> >> All suggestions welcome.
> > I think the best solution forward is to use threading.local to store > the request.user. So, something like this should work: > - have a middleware that stores the request.user in threading.local > - database routers just fetch the request.user from the > threading.local storage. Thanks Anssi! Here is my solution, I wonder if you could just tell me if you think there's a major problem with it. In simplistic terms, the goal is "whenever a model from wxdatabase is accessed, route the query to the database specified in the user's organization's field". It consists of a piece of django middleware and a db_router. I guess my main question is: am I using threading.local() correctly? Cheers! Tom ################################## ################################## import threading _local = threading.local() class WXDatabaseMiddleware(object): def process_request(self, request): _local.wx_database_label = None try: profile = request.user.get_profile() _local.wx_database_label = profile.organization.database.label except: ## This exception needs to be logged! pass class WxRouter(object): def _get_database_label(self): return _local.wx_database_label def read_and_write(self, model, **hints): if model._meta.app_label == "wxdatabase": return self._get_database_label() else: return None db_for_read = read_and_write db_for_write = read_and_write ################################### ###################################
signature.asc
Description: OpenPGP digital signature