Skip to content

Commit

Permalink
feat: add visibiilities to relationships
Browse files Browse the repository at this point in the history
  • Loading branch information
Yelinz committed Nov 17, 2023
1 parent 8caaaa7 commit b39afec
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python: [3.6, 3.7, 3.8, 3.9.0-rc - 3.9]
python: [3.7, 3.8, 3.9, 3.10]
steps:
- uses: actions/checkout@v2
- name: Setup Python
Expand Down
30 changes: 27 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,34 @@ For the visibilities, extend your DRF `ViewSet` classes with the
from rest_framework.viewsets import ModelViewSet
from generic_permissions.visibilities import VisibilityViewMixin
class MyModelViewset(VisibilityViewMixin, ModelViewSet):
serializer_class = ...
serializer_class = MyModelSerializers
queryset = ...
```

Make sure to use a subclassed `serializer_related_field` (such as the default `PrimariyKeyRelatedField`)
with the provided `VisibilityRelatedFieldMixin`. Otherwise relationships will leak hidden models.

```python
# serializers.py
from rest_framework.viewsets import ModelSerializer
from generic_permissions.visibilities import VisibilityPrimaryKeyRelatedField
class MyModelSerializers(ModelSerializer):
serializer_related_field = VisibilityPrimaryKeyRelatedField
```

A few subclassed fields are provided:
- `VisibilityPrimaryKeyRelatedField`
- `VisibilityResourceRelatedField`
- `VisibilitySerializerMethodResourceRelatedField`

If a different relation field variation is needed extend it with `VisibilityRelatedFieldMixin`:

```python
from generic_permissions.visibilities import VisibilityRelatedFieldMixin
class CustomRelationField(VisibilityRelatedFieldMixin):
pass
```

### Permission subsystem

Similarly, for the permissions system, add the `PermissionViewMixin` to your
Expand All @@ -94,13 +118,13 @@ You may use only one of the two mixins, or both, depending on your needs.
Last, for the validation system, you extend your **serializer** with a mixin:
```python
# serializers.py
from rest_framework import serializers
from rest_framework.serializers import ModelSerializer

from generic_permissions.serializers import PermissionSerializerMixin
from generic_permissions.validation import ValidatorMixin

from myapp import models
class MyModelSerializer(ValidatorMixin, serializers.ModelSerializer):
class MyModelSerializer(ValidatorMixin, ModelSerializer):
# my field definitions...
class Meta:
model = models.MyModel
Expand Down
34 changes: 34 additions & 0 deletions generic_permissions/visibilities.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
from functools import reduce
from warnings import warn

from rest_framework.serializers import PrimaryKeyRelatedField
from rest_framework_json_api.relations import (
ResourceRelatedField,
SerializerMethodResourceRelatedField,
)

from .config import DGAPConfigManager, VisibilitiesConfig

"""
Expand Down Expand Up @@ -44,6 +50,34 @@ def get_queryset(self):
return queryset


class VisibilityRelatedFieldMixin:
def get_queryset(self):
queryset = super().get_queryset()

for handler in VisibilitiesConfig.get_handlers(queryset.model):
queryset = handler(
queryset, self.get_parent_serializer()._context["request"]
)

return queryset


class VisibilityPrimaryKeyRelatedField(
PrimaryKeyRelatedField, VisibilityRelatedFieldMixin
):
pass


class VisibilityResourceRelatedField(ResourceRelatedField, VisibilityRelatedFieldMixin):
pass


class VisibilitySerializerMethodResourceRelatedField(
SerializerMethodResourceRelatedField, VisibilityRelatedFieldMixin
):
pass


class BaseVisibility: # pragma: no cover
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
Expand Down
1 change: 0 additions & 1 deletion tests/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@


class Migration(migrations.Migration):

initial = True

dependencies = []
Expand Down
5 changes: 5 additions & 0 deletions tests/serializers.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
from rest_framework import serializers

from generic_permissions.validation import ValidatorMixin
from generic_permissions.visibilities import VisibilityPrimaryKeyRelatedField

from . import models


class TestModel1Serializer(ValidatorMixin, serializers.ModelSerializer):
serializer_related_field = VisibilityPrimaryKeyRelatedField

class Meta:
model = models.Model1
fields = "__all__"


class TestModel2Serializer(ValidatorMixin, serializers.ModelSerializer):
serializer_related_field = VisibilityPrimaryKeyRelatedField

class Meta:
model = models.Model2
fields = "__all__"
16 changes: 8 additions & 8 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,25 @@

[tox]
envlist =
{py36,py37,py38}-django22,
{py36,py37,py38}-django30,
{py36,py37,py38,py39}-django31,
{py38,py39}-latest,
{py37,py38,py39}-django31,
{py37,py38,py39}-django32,
{py38,py39,py3.10}-latest,
flake8, black

[latest]
deps =
https://github.com/django/django/archive/main.tar.gz
https://github.com/encode/django-rest-framework/archive/master.tar.gz
https://github.com/django-json-api/django-rest-framework-json-api/archive/master.tar.gz

[testenv]
deps=
django22: django~=2.2.0
django30: django~=3.0.0
django31: django~=3.1.0
django22: djangorestframework~=3.11.0
django30: djangorestframework~=3.11.0
django32: django~=3.2.0
django31: djangorestframework~=3.11.0
django32: djangorestframework~=3.14.0
django31: djangorestframework-jsonapi~=6.1.0
django32: djangorestframework-jsonapi~=6.1.0
latest: {[latest]deps}
pytest
pytest-cov
Expand Down

0 comments on commit b39afec

Please sign in to comment.