Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NEW: request paramenter + custom response added. #6

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,47 @@ class ArticleViewSet(
save_after_transition = False
```

### Access to `request` inside transitions

If `request` parameter is defined as one of transition callable parameters, then request object will be passed to the transition callable.

### Excluded transitions
To exclude some transitions to be exposed, add transition name to `excluded_transitions` attribute.

```python
class ArticleViewSet(
get_drf_fsm_mixin(Article),
viewsets.ModelViewSet,
):
queryset = Article.objects.all()
excluded_transitions = ["foo_transition"]
```

### Public transitions
To have whitlisted/public transitions to be exposed, add transition name to `public_transitions` attribute.

```python
class ArticleViewSet(
get_drf_fsm_mixin(Article),
viewsets.ModelViewSet,
):
queryset = Article.objects.all()
public_transitions = ["public_transition"]
```

### Customized response

To have customied response, add transition name to `return_result_of` attribute and return your desired response from your transittion callable.

```python
class ArticleViewSet(
get_drf_fsm_mixin(Article),
viewsets.ModelViewSet,
):
queryset = Article.objects.all()
return_result_of = ["foo_transition"]
```

### Permissions

Custom permissions should be defined on the model's transition method
Expand Down
23 changes: 20 additions & 3 deletions djangorestframework_fsm/viewset_mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,26 @@ def transition_action(self, request, *args, **kwargs):
if not has_transition_perm(transition_method, self.request.user):
raise exceptions.PermissionDenied

if transition_name in self.excluded_transitions:
raise exceptions.PermissionDenied

if self.public_transitions and (transition_name not in self.public_transitions):
raise exceptions.PermissionDenied

if hasattr(self, 'get_{0}_kwargs'.format(transition_name)):
transition_kwargs = getattr(self, 'get_{0}_kwargs'.format(transition_name))()
else:
transition_kwargs = {}

if 'by' in inspect.signature(transition_method).parameters.keys() and 'by' not in transition_kwargs:
signature = inspect.signature(transition_method)

if 'by' in signature.parameters and 'by' not in transition_kwargs:
transition_kwargs['by'] = self.request.user

transition_method(**transition_kwargs)
if 'request' in signature.parameters and 'request' not in transition_kwargs:
transition_kwargs['request'] = self.request

result = transition_method(**transition_kwargs)

if self.save_after_transition:
instance.save()
Expand All @@ -39,6 +50,9 @@ def transition_action(self, request, *args, **kwargs):
# forcibly invalidate the prefetch cache on the instance.
instance._prefetched_objects_cache = {}

if transition_name in self.return_result_of:
return Response(result)

serializer = self.get_serializer(instance)
return Response(serializer.data)

Expand All @@ -59,6 +73,9 @@ def get_drf_fsm_mixin(Model, fieldname='state'):

class Mixin(object):
save_after_transition = True
return_result_of = []
excluded_transitions = []
public_transitions = []

@action(methods=['GET'], detail=True, url_name='possible-transitions', url_path='possible-transitions')
def possible_transitions(self, request, *args, **kwargs):
Expand All @@ -68,7 +85,7 @@ def possible_transitions(self, request, *args, **kwargs):
'transitions': [
trans.name.replace('_', '-')
for trans in getattr(instance, 'get_available_{}_transitions'.format(fieldname))()
if trans.has_perm(instance, request.user)
if trans.has_perm(instance, request.user) and (trans.name not in self.excluded_transitions) and (trans.name in (self.public_transitions or [trans.name]))
]
},
)
Expand Down