Hi Fred, I don't see how it could possibly be thread-safe without using a thread-local. But, if you don't deploy using threads then you should be fine.
I agree with Russ that explicit is better than implicit. I think there is some benefit to simply being able to ask for the the current request object wherever you need it, though I've been able to avoid it pretty much every time. The main downside is that it simply doesn't work in the shell or any outside-request scripts. I imagine it's also harder to test. There are libraries out there to do the thread-local technique for you, but it's pretty much this simple: import threading store = threading.local() class Middleware: def process_request(self, request): store.request = request def process_response(self, request, response): del store.request return response Then you can access store.request wherever you want. Or, for fun, you can do far more evil with less code :) import inspect for line in inspect.stack(): if 'request' in line[0].f_locals: request = line[0].f_locals['request'] Collin On Sunday, December 14, 2014 8:15:14 PM UTC-5, Fred Stluka wrote: > > Collin and Russell (and anyone else), > > Do you have any opinion on this? > - https://bitbucket.org/aptivate/django-current-user > > It was offered in an earlier post: > - https://groups.google.com/d/msg/django-users/y7aIbN2_CsA/GtmrSjG1nq8J > > as a solution to exactly this problem. > > Makes the current user available to the save() method of all > models. > > I read the code and it looks good, but I don't know the details > of Apache/WSGI/Django/Python multi-threading well enough > to know if it is thread safe. > > It basically uses django.db.models. signals.pre_save.connect() > to get a callback called just before each save(), and that callback > was generated by a middleware layer to know what the current > user was for a request, so it sets a model field with a name like > update_user to the current user just before the save(). > > If there were 2 concurrent HTTP requests, would this work > reliably? Or would there just be 2 registered callbacks, that > would overwrite each other's values in the update_user field > before the save()? If so, one user would be recorded for saves > done by both requests. > > It seems to me that this would work fine if each HTTP request > was handled by a separate process, but not if handled by > separate threads that share the same memory, and presumably > the same signals and callbacks. > > Thoughts? > --Fred > ------------------------------ > Fred Stluka -- mailt...@bristle.com <javascript:> -- > http://bristle.com/~fred/ > Bristle Software, Inc -- http://bristle.com -- Glad to be of service! > Open Source: Without walls and fences, we need no Windows or Gates. > ------------------------------ > On 12/14/14 2:13 PM, Collin Anderson wrote: > > Hi, > > The "admin save handlers" refers to save_model() and there's actually a > nice example of accessing the user. > > https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.save_model > > If you're using the admin, that's a good place to record this sort of > thing. > > Using a middleware is also helpful for a more general approach, though > be careful because connections can now be re-used over multiple requests. > Also, if you're deploying using threading, be sure what you are doing is > thread-safe. > > Collin > > On Friday, December 12, 2014 5:29:35 AM UTC-5, malt...@gmail.com wrote: >> >> Thanks Mike and Russell, this is very helpful for starters. Do you have >> some more verbose code examples I can use as crutches while I hobble along >> the path of understanding Django? Especially an expansion on something like >> "All the admin save handlers" would be much appreciated. >> >> For me every change needs to be tracked, not just ones from the admin >> realm, and the audit trail entry is written by a trigger function which >> gets the current user name from a variable set for the postgres connection. >> My quest so far was to find the magical place where I have access to the >> request (for the username) and the db.connection (for setting the database >> variable), which – if I understand correctly – does not exist. So right now >> I was about writing my own middleware class with a process_view. Would that >> be the right place and how would I introduce the username into the data >> flow? >> >> >> Sincerely, >> >> Malte >> > -- > You received this message because you are subscribed to the Google Groups > "Django users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to django-users...@googlegroups.com <javascript:>. > To post to this group, send email to django...@googlegroups.com > <javascript:>. > Visit this group at http://groups.google.com/group/django-users. > To view this discussion on the web visit > https://groups.google.com/d/msgid/django-users/561482b8-a4bf-44fd-9c7d-ef2bbec54726%40googlegroups.com > > <https://groups.google.com/d/msgid/django-users/561482b8-a4bf-44fd-9c7d-ef2bbec54726%40googlegroups.com?utm_medium=email&utm_source=footer> > . > For more options, visit https://groups.google.com/d/optout. > > > -- You received this message because you are subscribed to the Google Groups "Django users" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscr...@googlegroups.com. To post to this group, send email to django-users@googlegroups.com. Visit this group at http://groups.google.com/group/django-users. To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/2a5b12a7-df82-4cfb-8951-668b02d9d5b7%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.