add back api for collection

This commit is contained in:
Dmitriy Kuzmenko 2019-11-20 16:29:46 +03:00
parent d932df4392
commit 2e17d7265d
4 changed files with 133 additions and 19 deletions

View File

@ -1,8 +1,14 @@
from rest_framework import serializers from rest_framework import serializers
from collection import models
from collection.serializers.common import CollectionBaseSerializer
from establishment.models import Establishment
from location.models import Country from location.models import Country
from location.serializers import CountrySimpleSerializer from location.serializers import CountrySimpleSerializer
from collection.serializers.common import CollectionBaseSerializer from product.models import Product
from collection import models from utils.exceptions import (
BindingObjectNotFound, RemovedBindingObjectNotFound, ObjectAlreadyAdded
)
class CollectionBackOfficeSerializer(CollectionBaseSerializer): class CollectionBackOfficeSerializer(CollectionBaseSerializer):
@ -31,3 +37,54 @@ class CollectionBackOfficeSerializer(CollectionBaseSerializer):
'start', 'start',
'end', 'end',
] ]
class CollectionBindObjectSerializer(serializers.Serializer):
"""Serializer for binding collection and objects"""
ESTABLISHMENT = 'establishment'
PRODUCT = 'product'
TYPE_CHOICES = (
(ESTABLISHMENT, 'Establishment'),
(PRODUCT, 'Product'),
)
type = serializers.ChoiceField(TYPE_CHOICES)
object_id = serializers.IntegerField()
def validate(self, attrs):
view = self.context.get('view')
request = self.context.get('request')
obj_type = attrs.get('type')
obj_id = attrs.get('object_id')
collection = view.get_object()
attrs['collection'] = collection
if obj_type == self.ESTABLISHMENT:
establishment = Establishment.objects.filter(pk=obj_id).\
first()
if not establishment:
raise BindingObjectNotFound()
if request.method == 'POST' and collection.establishments.\
filter(pk=establishment.pk).exists():
raise ObjectAlreadyAdded()
if request.method == 'DELETE' and not collection.\
establishments.filter(pk=establishment.pk).\
exists():
raise RemovedBindingObjectNotFound()
attrs['related_object'] = establishment
elif obj_type == self.PRODUCT:
product = Product.objects.filter(pk=obj_id).first()
if not product:
raise BindingObjectNotFound()
if request.method == 'POST' and collection.products.\
filter(pk=product.pk).exists():
raise ObjectAlreadyAdded()
if request.method == 'DELETE' and not collection.products.\
filter(pk=product.pk).exists():
raise RemovedBindingObjectNotFound()
attrs['related_object'] = product
return attrs

View File

@ -1,11 +1,10 @@
"""Collection common urlpaths.""" """Collection common urlpaths."""
from django.urls import path from rest_framework.routers import SimpleRouter
from collection.views import back as views from collection.views import back as views
app_name = 'collection' app_name = 'collection'
router = SimpleRouter()
router.register(r'', views.CollectionBackOfficeViewSet)
urlpatterns = [ urlpatterns = router.urls
path('', views.CollectionListCreateView.as_view(), name='list-create'),
path('<int:pk>/', views.CollectionRUDView.as_view(), name='rud-collection'),
]

View File

@ -1,19 +1,49 @@
from rest_framework import generics, permissions from rest_framework import permissions
from rest_framework import viewsets, mixins
from collection import models from collection import models
from collection.serializers import back from collection.serializers import back as serializers
from utils.views import BindObjectMixin
class CollectionListCreateView(generics.ListCreateAPIView): class CollectionViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
"""Collection list-create view.""" """ViewSet for Collection model."""
pagination_class = None
permission_classes = (permissions.AllowAny,)
queryset = models.Collection.objects.all() queryset = models.Collection.objects.all()
serializer_class = back.CollectionBackOfficeSerializer serializer_class = serializers.CollectionBackOfficeSerializer
# todo: conf. permissions by TT
permission_classes = (permissions.IsAuthenticated, )
class CollectionRUDView(generics.RetrieveUpdateDestroyAPIView): class CollectionBackOfficeViewSet(mixins.CreateModelMixin,
"""Collection list-create view.""" mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.RetrieveModelMixin,
BindObjectMixin,
CollectionViewSet):
"""ViewSet for Collection model for BackOffice users."""
permission_classes = (permissions.IsAuthenticated,)
queryset = models.Collection.objects.all() queryset = models.Collection.objects.all()
serializer_class = back.CollectionBackOfficeSerializer serializer_class = serializers.CollectionBackOfficeSerializer
# todo: conf. permissions by TT bind_object_serializer_class = serializers.CollectionBindObjectSerializer
permission_classes = (permissions.IsAuthenticated, )
def perform_binding(self, serializer):
data = serializer.validated_data
collection = data.pop('collection')
obj_type = data.get('type')
related_object = data.get('related_object')
if obj_type == self.bind_object_serializer_class.ESTABLISHMENT:
collection.establishments.add(related_object)
elif obj_type == self.bind_object_serializer_class.PRODUCT:
collection.products.add(related_object)
def perform_unbinding(self, serializer):
data = serializer.validated_data
collection = data.pop('collection')
obj_type = data.get('type')
related_object = data.get('related_object')
if obj_type == self.bind_object_serializer_class.ESTABLISHMENT:
collection.establishments.remove(related_object)
elif obj_type == self.bind_object_serializer_class.PRODUCT:
collection.products.remove(related_object)

View File

@ -4,6 +4,7 @@ from django.conf import settings
from django.db.transaction import on_commit from django.db.transaction import on_commit
from rest_framework import generics from rest_framework import generics
from rest_framework import status from rest_framework import status
from rest_framework.decorators import action
from rest_framework.response import Response from rest_framework.response import Response
from gallery.tasks import delete_image from gallery.tasks import delete_image
@ -121,3 +122,30 @@ class CreateDestroyGalleryViewMixin(generics.CreateAPIView,
# Delete an instances of Gallery model # Delete an instances of Gallery model
gallery_obj.delete() gallery_obj.delete()
return Response(status=status.HTTP_204_NO_CONTENT) return Response(status=status.HTTP_204_NO_CONTENT)
# BackOffice user`s views & viewsets
class BindObjectMixin:
"""Bind object mixin."""
def get_serializer_class(self):
if self.action == 'bind_object':
return self.bind_object_serializer_class
return self.serializer_class
def perform_binding(self, serializer):
raise NotImplemented
def perform_unbinding(self, serializer):
raise NotImplemented
@action(methods=['post', 'delete'], detail=True, url_path='bind-object')
def bind_object(self, request, pk=None):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
if request.method == 'POST':
self.perform_binding(serializer)
return Response(serializer.data, status=status.HTTP_201_CREATED)
elif request.method == 'DELETE':
self.perform_unbinding(serializer)
return Response(status=status.HTTP_204_NO_CONTENT)