2019-02-28 08:31:04 +00:00
|
|
|
from django.db import transaction
|
|
|
|
|
2019-01-11 12:33:35 +00:00
|
|
|
from rest_framework import decorators
|
2019-02-28 08:31:04 +00:00
|
|
|
from rest_framework import exceptions
|
|
|
|
from rest_framework import response
|
|
|
|
from rest_framework import status
|
|
|
|
|
|
|
|
from . import filters
|
|
|
|
from . import models
|
|
|
|
from . import mutations as common_mutations
|
|
|
|
from . import serializers
|
|
|
|
from . import signals
|
|
|
|
from . import tasks
|
|
|
|
from . import utils
|
2019-01-09 13:18:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
def action_route(serializer_class):
|
2019-01-11 12:33:35 +00:00
|
|
|
@decorators.action(methods=["post"], detail=False)
|
2019-01-09 13:18:32 +00:00
|
|
|
def action(self, request, *args, **kwargs):
|
|
|
|
queryset = self.get_queryset()
|
|
|
|
serializer = serializer_class(request.data, queryset=queryset)
|
|
|
|
serializer.is_valid(raise_exception=True)
|
|
|
|
result = serializer.save()
|
|
|
|
return response.Response(result, status=200)
|
|
|
|
|
|
|
|
return action
|
2019-02-28 08:31:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
def mutations_route(types):
|
|
|
|
"""
|
|
|
|
Given a queryset and a list of mutation types, return a view
|
|
|
|
that can be included in any viewset, and serve:
|
|
|
|
|
|
|
|
GET /{id}/mutations/ - list of mutations for the given object
|
|
|
|
POST /{id}/mutations/ - create a mutation for the given object
|
|
|
|
"""
|
|
|
|
|
|
|
|
@transaction.atomic
|
|
|
|
def mutations(self, request, *args, **kwargs):
|
|
|
|
obj = self.get_object()
|
|
|
|
if request.method == "GET":
|
|
|
|
queryset = models.Mutation.objects.get_for_target(obj).filter(
|
|
|
|
type__in=types
|
|
|
|
)
|
|
|
|
queryset = queryset.order_by("-creation_date")
|
|
|
|
filterset = filters.MutationFilter(request.GET, queryset=queryset)
|
|
|
|
page = self.paginate_queryset(filterset.qs)
|
|
|
|
if page is not None:
|
|
|
|
serializer = serializers.APIMutationSerializer(page, many=True)
|
|
|
|
return self.get_paginated_response(serializer.data)
|
|
|
|
|
|
|
|
serializer = serializers.APIMutationSerializer(queryset, many=True)
|
|
|
|
return response.Response(serializer.data)
|
|
|
|
if request.method == "POST":
|
|
|
|
if not request.user.is_authenticated:
|
|
|
|
raise exceptions.NotAuthenticated()
|
|
|
|
serializer = serializers.APIMutationSerializer(
|
|
|
|
data=request.data, context={"registry": common_mutations.registry}
|
|
|
|
)
|
|
|
|
serializer.is_valid(raise_exception=True)
|
|
|
|
if not common_mutations.registry.has_perm(
|
|
|
|
actor=request.user.actor,
|
|
|
|
type=serializer.validated_data["type"],
|
|
|
|
obj=obj,
|
|
|
|
perm="approve"
|
|
|
|
if serializer.validated_data.get("is_approved", False)
|
|
|
|
else "suggest",
|
|
|
|
):
|
|
|
|
raise exceptions.PermissionDenied()
|
|
|
|
|
|
|
|
final_payload = common_mutations.registry.get_validated_payload(
|
|
|
|
type=serializer.validated_data["type"],
|
|
|
|
payload=serializer.validated_data["payload"],
|
|
|
|
obj=obj,
|
|
|
|
)
|
|
|
|
mutation = serializer.save(
|
|
|
|
created_by=request.user.actor,
|
|
|
|
target=obj,
|
|
|
|
payload=final_payload,
|
|
|
|
is_approved=serializer.validated_data.get("is_approved", None),
|
|
|
|
)
|
|
|
|
if mutation.is_approved:
|
|
|
|
utils.on_commit(tasks.apply_mutation.delay, mutation_id=mutation.pk)
|
|
|
|
|
|
|
|
utils.on_commit(
|
|
|
|
signals.mutation_created.send, sender=None, mutation=mutation
|
|
|
|
)
|
|
|
|
return response.Response(serializer.data, status=status.HTTP_201_CREATED)
|
|
|
|
|
2019-03-25 16:02:51 +00:00
|
|
|
return decorators.action(
|
|
|
|
methods=["get", "post"], detail=True, required_scope="edits"
|
|
|
|
)(mutations)
|