I have a Django app which has a single-account model. We are converting this to be multi-account, so almost every model will have a ForeignKey(Account)
.
This snippet might put you in the right direction. I believe row level permissions are on the todo list for 1.2 also, not 100% sure on that one though.
I don't think there is any clear winner, especially if you consider that not all queries will need to be filtered by account. Also consider the old threadlocals
trick is considered unreliable which means the only way to do automatic insertion of filter parameters would be with middleware I guess... but that also seems unreliable and complex to me.
I also haven't come up with a good way to make a query manager that can help here, but it might be possible.
So, I think the best solution for a "multi-tenant" database is just to make sure all your queries are filtered by account. You can do this with:
Debug mode middleware such as Middleware: Record ownership screener
In your tests check the sql generated by any tests and verify the account field is in the query. You could also include "other account" data in your test fixtures that your test would make sure do not show up in any query results.
Making sure all queries are checked for the filter during code review
Certainly not pretty, but the best I've been able to do so far.
Are you using django.contrib.auth
?
If you are, just make Account a ForeignKey(User, unique=true)
and point all your models at User
ie. ForeignKey(User)
Also, Take a look at the django Auth Docs
edit: I think I understand your concern a little better now...
Instead of doing
my_model.objects.filter(user=request.user)
just do:
request.user.my_model_set.all()
Is there some huge reason why you can't just write a function that automatically inserts the session account into the query and takes all your other parameters as arguments?
Wow, I'm having the exact same problem. Here's the best answer I got:
Django: How would one organize this big model / manager / design mess?