Matthias Kestenholz wrote:
> On Mon, Jul 20, 2009 at 9:26 AM, Bartłomiej Górny<bar...@gorny.edu.pl> wrote:
>> [...]
>>> there is a cookbook recipe for achieving this sort of thing:
>>>
>>> http://code.djangoproject.com/wiki/CookBookThreadlocalsAndUser
>> Yep, that's exactly what I did :)
>>
>>> That's deep in the category of 'give them rope to hang themselves
>>> with' though. You should understand the implications and design
>>> decisions involved before hacking your way around it.
>> I give +1 to Joshua's request - plz explain.
>>
> 
> thread locals have all the problems which are generally associated
> with global variables. They might be overwritten by other code, they
> make testing extremely difficult because the behavior of methods may
> depend on non-obvious circumstances and it's not clear from the method
> signatures which variables are really used -- in short, it makes code
> maintenance much harder than it needs to be.
> 

Thanks for explaining that - I see your point, and I generally agree, 
though I'd like to comment on a couple of things:

> I'll try giving a few examples:
> 
> - You have a field on your model called last_modified_by, and you
> automatically assign request.user in the save() method. You made this
> piece of code much harder to test in an unittest than it needs to be,
> because now you have to provide the complete environment including the
> variables from the threadlocals space in your testsuite. More code is
> needed, and the probability that the code and the testsuite (and
> eventual documentation) get out of sync gets bigger and bigger.

Actually, not necessarily - in testing environment you can simply 
replace the function that gives you current user. Though I understand 
that some people may find it disgusting.

> - Something which I've done for a CRM system which we've developped
> for internal use together with another company was giving Tasks access
> levels, so that we were able to make certain tasks viewable only by
> the management. I built a manager which uses the user information from
> thread local space to filter the queryset automatically according to
> the profile of the currently authenticated user. With this seemingly
> simple move I've made it impossible to use loaddata/dumpdata, because
> no user exists, and I made it very non-obvious that the list of
> viewable tasks depends on the user. You would not get the idea that
> filtering is going on in the templates or even in a big part of the
> code. This is not a big problem when developping alone, but it can
> really hamper progress if someone else takes over the codebase.
> 

True. For getting/filtering, user should be passed explicitly.

> In short: It's easy and it gets the job done, but will come back and
> bite you later for sure. Don't give in to the temptation -- it's much
> better to write custom template tags where you can pass the user
> explicitly to the function, which makes it very clear that the
> output/the result of a certain function depends on the user. It also
> makes testing a breeze, because the behavior of methods is only
> determined by their arguments (as it should be), not by other
> circumstances or the current weather.

There are two sides to that - for view functions, you can write 
templatetags. But you have also to create and save objects, and then you 
have to set or pass the user manually every time you create or save 
anything anywhere in your code. This means more typing, and it is also 
easy to forget about it, so you get another kind of trouble. As far as 
I'm concerned, the main use of this way of getting user is creating 
objects, not filtering.

Bartek

> 



> 
> Matthias
> 
> > 


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to