Skip to content

Commit a68d266

Browse files
author
Ryan P Kilby
committed
Deprecate DjangoObjectPermissionsFilter
1 parent a027791 commit a68d266

File tree

5 files changed

+37
-5
lines changed

5 files changed

+37
-5
lines changed

docs/api-guide/filtering.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,12 @@ The `ordering` attribute may be either a string or a list/tuple of strings.
285285

286286
The `DjangoObjectPermissionsFilter` is intended to be used together with the [`django-guardian`][guardian] package, with custom `'view'` permissions added. The filter will ensure that querysets only returns objects for which the user has the appropriate view permission.
287287

288+
---
289+
290+
**Note:** This filter has been deprecated as of version 3.9 and moved to the 3rd-party [`djangorestframework-guardian` package][django-rest-framework-guardian].
291+
292+
---
293+
288294
If you're using `DjangoObjectPermissionsFilter`, you'll probably also want to add an appropriate object permissions class, to ensure that users can only operate on instances if they have the appropriate object permissions. The easiest way to do this is to subclass `DjangoObjectPermissions` and add `'view'` permissions to the `perms_map` attribute.
289295

290296
A complete example using both `DjangoObjectPermissionsFilter` and `DjangoObjectPermissions` might look something like this.
@@ -388,6 +394,7 @@ The [djangorestframework-word-filter][django-rest-framework-word-search-filter]
388394
[view-permissions-blogpost]: https://blog.nyaruka.com/adding-a-view-permission-to-django-models
389395
[search-django-admin]: https://docs.djangoproject.com/en/stable/ref/contrib/admin/#django.contrib.admin.ModelAdmin.search_fields
390396
[django-rest-framework-filters]: https://github.com/philipn/django-rest-framework-filters
397+
[django-rest-framework-guardian]: https://github.com/rpkilby/django-rest-framework-guardian
391398
[django-rest-framework-word-search-filter]: https://github.com/trollknurr/django-rest-framework-word-search-filter
392399
[django-url-filter]: https://github.com/miki725/django-url-filter
393400
[drf-url-filter]: https://github.com/manjitkumar/drf-url-filters

docs/api-guide/permissions.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,7 @@ As with `DjangoModelPermissions` you can use custom model permissions by overrid
168168

169169
---
170170

171-
**Note**: If you need object level `view` permissions for `GET`, `HEAD` and `OPTIONS` requests, you'll want to consider also adding the `DjangoObjectPermissionsFilter` class to ensure that list endpoints only return results including objects for which the user has appropriate view permissions.
172-
173-
---
171+
**Note**: If you need object level `view` permissions for `GET`, `HEAD` and `OPTIONS` requests and are using django-guardian for your object-level permissions backend, you'll want to consider using the `DjangoObjectPermissionsFilter` class provided by the [`djangorestframework-guardian` package][django-rest-framework-guardian]. It ensures that list endpoints only return results including objects for which the user has appropriate view permissions.
174172

175173
---
176174

@@ -287,3 +285,4 @@ The [Django Rest Framework Role Filters][django-rest-framework-role-filters] pac
287285
[django-rest-framework-roles]: https://github.com/computer-lab/django-rest-framework-roles
288286
[django-rest-framework-api-key]: https://github.com/manosim/django-rest-framework-api-key
289287
[django-rest-framework-role-filters]: https://github.com/allisson/django-rest-framework-role-filters
288+
[django-rest-framework-guardian]: https://github.com/rpkilby/django-rest-framework-guardian

docs/community/release-notes.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ You can determine your currently installed version using `pip show`:
4646

4747
* Deprecate the `Router.register` `base_name` argument in favor of `basename`. [#5990][gh5990]
4848
* Deprecate the `Router.get_default_base_name` method in favor of `Router.get_default_basename`. [#5990][gh5990]
49+
* Deprecate the `DjangoObjectPermissionsFilter` class, moved to the `djangorestframework-guardian` package. [#6075][gh6075]
4950

5051

5152
## 3.8.x series
@@ -1974,3 +1975,4 @@ For older release notes, [please see the version 2.x documentation][old-release-
19741975

19751976
<!-- 3.9.0 -->
19761977
[gh5990]: https://github.com/encode/django-rest-framework/issues/5990
1978+
[gh6075]: https://github.com/encode/django-rest-framework/issues/6075

rest_framework/filters.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from __future__ import unicode_literals
66

77
import operator
8+
import warnings
89
from functools import reduce
910

1011
from django.core.exceptions import ImproperlyConfigured
@@ -284,6 +285,11 @@ class DjangoObjectPermissionsFilter(BaseFilterBackend):
284285
has read object level permissions.
285286
"""
286287
def __init__(self):
288+
warnings.warn(
289+
"`DjangoObjectPermissionsFilter` has been deprecated and moved to "
290+
"the 3rd-party django-rest-framework-guardian package.",
291+
DeprecationWarning, stacklevel=2
292+
)
287293
assert is_guardian_installed(), 'Using DjangoObjectPermissionsFilter, but django-guardian is not installed'
288294

289295
perm_format = '%(app_label)s.view_%(model_name)s'

tests/test_permissions.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import base64
44
import unittest
5+
import warnings
56

67
import django
78
from django.contrib.auth.models import Group, Permission, User
@@ -417,17 +418,34 @@ def test_can_read_get_queryset_permissions(self):
417418
self.assertEqual(response.status_code, status.HTTP_200_OK)
418419

419420
# Read list
421+
def test_django_object_permissions_filter_deprecated(self):
422+
with warnings.catch_warnings(record=True) as w:
423+
warnings.simplefilter("always")
424+
DjangoObjectPermissionsFilter()
425+
426+
message = ("`DjangoObjectPermissionsFilter` has been deprecated and moved "
427+
"to the 3rd-party django-rest-framework-guardian package.")
428+
self.assertEqual(len(w), 1)
429+
self.assertIs(w[-1].category, DeprecationWarning)
430+
self.assertEqual(str(w[-1].message), message)
431+
420432
def test_can_read_list_permissions(self):
421433
request = factory.get('/', HTTP_AUTHORIZATION=self.credentials['readonly'])
422434
object_permissions_list_view.cls.filter_backends = (DjangoObjectPermissionsFilter,)
423-
response = object_permissions_list_view(request)
435+
# TODO: remove in version 3.10
436+
with warnings.catch_warnings(record=True):
437+
warnings.simplefilter("always")
438+
response = object_permissions_list_view(request)
424439
self.assertEqual(response.status_code, status.HTTP_200_OK)
425440
self.assertEqual(response.data[0].get('id'), 1)
426441

427442
def test_cannot_read_list_permissions(self):
428443
request = factory.get('/', HTTP_AUTHORIZATION=self.credentials['writeonly'])
429444
object_permissions_list_view.cls.filter_backends = (DjangoObjectPermissionsFilter,)
430-
response = object_permissions_list_view(request)
445+
# TODO: remove in version 3.10
446+
with warnings.catch_warnings(record=True):
447+
warnings.simplefilter("always")
448+
response = object_permissions_list_view(request)
431449
self.assertEqual(response.status_code, status.HTTP_200_OK)
432450
self.assertListEqual(response.data, [])
433451

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy