I think it is a good idea to do the permission check on the manager level. I would prefer a more explicit approach, e.g. something like this:
MyModel.objects.for_user(request.user).all() MyModel.objects.for_all_users().all() MyModel.objects.all() -> raises Exception This way you don't need a middleware, have less global state and you keep your manager decoupled from the request. It's a bit more typing though :) Cheers, Daniel Hepper https://consideratecode.com On Thursday, March 9, 2017 at 1:37:20 PM UTC+1, Antonis Christofides wrote: > > So you've rebranded your problem from "remembering to do this in views" to > "remembering you've used the right model manager". > > No, because I do this in the default manager, "objects", and I create a > new manager, "all_objects", for the exceptional case I actually want to get > all objects in a view, without checking permissions. > > The obvious reason for not tying a model to a request, is that you cannot > obtain instances without a request (management commands, among which data > migrations). > > Of course you can. I explained it in my original message: "If there is no > request object stored in the thread local variable, the manager assumes > this query does not come from the web and does not filter it." > > tests are the place to assert you did (if you remember to write a test for > it ...). > > Exactly, "if you remember to write a test". Unit tests can help, but when > you do the same kind of permissions checking 10 times in 10 different > places of the app, it's really hard to know that you failed to check edge > case XYZ. > > Antonis Christofideshttp://djangodeployment.com > > > On 03/09/2017 01:28 PM, Melvyn Sopacua wrote: > > On Thursday 09 March 2017 12:51:26 Antonis Christofides wrote: > > > > > One solution that I've implemented in an app is to have middleware > > > that stores the request in a thread local variable. The model manager > > > gets the request from there and filters the results accordingly. If > > > there is no request object stored in the thread local variable, the > > > manager assumes this query does not come from the web and does not > > > filter it. > > > > > > Is this a good way to do it? Is there any alternative? > > > > So you've rebranded your problem from "remembering to do this in views" to > "remembering you've used the right model manager". > > The only way to solve it, is to use a default-deny authentication backend, > where the view needs to whitelist permissions. That way never anything > leaks and your memory is no longer a factor in the problem. > > But....it assumes one url handles one object, which isn't the case in most > projects. > > > > The obvious reason for not tying a model to a request, is that you cannot > obtain instances without a request (management commands, among which data > migrations). > > > > You have to remember something somewhere and tests are the place to assert > you did (if you remember to write a test for it ...). > > -- > > Melvyn Sopacua > -- > 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 https://groups.google.com/group/django-users. > To view this discussion on the web visit > https://groups.google.com/d/msgid/django-users/1570464.pXdMm1KXXq%40devstation > > <https://groups.google.com/d/msgid/django-users/1570464.pXdMm1KXXq%40devstation?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 https://groups.google.com/group/django-users. To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/27fd4278-d439-49e3-8217-9b129aff3a84%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.