| | 145 | |
|---|
| | 146 | QuerySet Filtering by Permissions |
|---|
| | 147 | --------------------------------- |
|---|
| | 148 | |
|---|
| | 149 | Checking permissions on a single object only solves half of the problem. We |
|---|
| | 150 | also need a way to get a list of objects for which a user has a given permission. |
|---|
| | 151 | |
|---|
| | 152 | This is implemented as a function for now, but it might be more desirable to |
|---|
| | 153 | be a method of QuerySet. We'll just to use plain old functions to start with, |
|---|
| | 154 | then we'll test the extensible function version. |
|---|
| | 155 | |
|---|
| | 156 | >>> def owner_filter(user, permission, queryset): |
|---|
| | 157 | ... return queryset.filter(creator=user) |
|---|
| | 158 | ... |
|---|
| | 159 | |
|---|
| | 160 | >>> user_2 = User.objects.create_user('user 2', 'test@example.com', 'password') |
|---|
| | 161 | >>> user_2.save() |
|---|
| | 162 | |
|---|
| | 163 | >>> article_1 = Article(title='article 1', body='article 1', creator=user_2) |
|---|
| | 164 | >>> article_1.save() |
|---|
| | 165 | >>> article_2 = Article(title='article 2', body='article 2', creator=user) |
|---|
| | 166 | >>> article_2.save() |
|---|
| | 167 | >>> article_3 = Article(title='article 3', body='article 3', creator=user) |
|---|
| | 168 | >>> article_3.save() |
|---|
| | 169 | |
|---|
| | 170 | >>> qs = owner_filter(user, change_permission, Article.objects.all()) |
|---|
| | 171 | >>> qs.count() |
|---|
| | 172 | 3 |
|---|
| | 173 | >>> [a.title for a in qs] |
|---|
| | 174 | ['test', 'article 2', 'article 3'] |
|---|
| | 175 | |
|---|
| | 176 | |
|---|
| | 177 | QuerySetFilter is a craptacular name... let's change that. |
|---|
| | 178 | |
|---|
| | 179 | >>> class QuerySetFilter(object): |
|---|
| | 180 | ... def __init__(self): |
|---|
| | 181 | ... self.registry = {} |
|---|
| | 182 | ... |
|---|
| | 183 | ... def __call__(self, user, permission, queryset): |
|---|
| | 184 | ... types = (type(user), type(permission), queryset.model) |
|---|
| | 185 | ... #print "Looking up types: " + types.__repr__() |
|---|
| | 186 | ... func = self.registry.get(types) |
|---|
| | 187 | ... if func: |
|---|
| | 188 | ... return func(user, permission, queryset) |
|---|
| | 189 | ... else: |
|---|
| | 190 | ... return queryset |
|---|
| | 191 | ... |
|---|
| | 192 | ... def register(self, func, user_type, permission_type, qs_model_type): |
|---|
| | 193 | ... types = (user_type, permission_type, qs_model_type) |
|---|
| | 194 | ... #print "Registering types: " + types.__repr__() |
|---|
| | 195 | ... self.registry[types] = func |
|---|
| | 196 | ... |
|---|
| | 197 | |
|---|
| | 198 | Now try the same stuff using the extensible function. |
|---|
| | 199 | |
|---|
| | 200 | >>> qs_filter = QuerySetFilter() |
|---|
| | 201 | >>> qs_filter.register(owner_filter, User, Permission, Article) |
|---|
| | 202 | |
|---|
| | 203 | >>> qs = qs_filter(user, change_permission, Article.objects.all()) |
|---|
| | 204 | >>> qs.count() |
|---|
| | 205 | 3 |
|---|
| | 206 | >>> [a.title for a in qs] |
|---|
| | 207 | ['test', 'article 2', 'article 3'] |
|---|
| | 208 | |
|---|