from django.conf import settings from rest_framework import viewsets, serializers as rf_serializers from rest_framework.permissions import IsAuthenticated, IsAdminUser from rest_framework.response import Response from rest_framework_jwt.authentication import JSONWebTokenAuthentication from rest_framework.decorators import permission_classes from django.shortcuts import get_object_or_404 from brew_data import models, serializers from accounts.auth import TokenAuthentication from django.contrib.contenttypes.models import ContentType class FermentableTypes(viewsets.ViewSet): """ View to Retrieve Fermentable ingredient Types. """ authentication_classes = (JSONWebTokenAuthentication, TokenAuthentication) # def get_permissions(self): # """Define custom permissions for different methods""" # # at minimum require users to be authenticated # self.permission_classes = [IsAuthenticated] # # for PUT requests require users to be admins # if self.request.method == 'PUT': # self.permission_classes.append(IsAdminUser) # return super(viewsets.ViewSet, self).get_permissions() def list(self, request): """ Returns all fermentable types in the system """ fermentable_types = fermentable_types = models.FermentableType.objects.filter(is_active=True) # if the user is authenticated return all valid fermentable types if request.auth is None: fermentable_types = fermentable_types[:settings.UNAUTHENTICATED_RESULTS_COUNT] serializer = rf_serializers.ListSerializer( fermentable_types, child=serializers.FermentableType() ) return Response(serializer.data) def update(self, request, pk=None): """Allows admins to edit fermentable types directly.""" fermentable_type = get_object_or_404(models.FermentableType, pk=pk) serializer = serializers.FermentableType(data=request.data) if serializer.is_valid(): fermentable_type = serializer.save() # if the fermentable was marked as is_active then set that flag if request.data['is_active'] is not None: fermentable_type.is_active = request.data['is_active'] fermentable_type.save() return Response(serializer.data) else: return Response(serializer.errors) def create(self, request): """ Suggests a brand new fermentable type. """ serializer = serializers.FermentableTypeSuggestion(data=request.data) if serializer.is_valid(): suggestion = serializer.save() suggestion = models.Suggestion.objects.get(id=suggestion.id) new_type = models.FermentableType.objects.get(id=suggestion.suggested_object_id) new_type_data = serializers.FermentableType(new_type).data data = { "old_type_id": suggestion.replaced_object_id, "new_type": new_type_data } return Response(data) else: return Response(serializer.errors) class FermentableInstances(viewsets.ViewSet): """ View to retrieve/update fermentable instances. """ authentication_classes = (JSONWebTokenAuthentication, TokenAuthentication) def get_permissions(self): """Define custom permissions for different methods""" # at minimum require users to be authenticated self.permission_classes = [IsAuthenticated] # for PUT requests require users to be admins if self.request.method == 'PUT': self.permission_classes.append(IsAdminUser) return super(viewsets.ViewSet, self).get_permissions() def create(self, request): """ Create a new suggestion for a fermentable instance. """ serializer = serializers.FermentableInstanceSuggestion(data=request.data) if serializer.is_valid(): suggestion = serializer.save() suggestion = models.Suggestion.objects.get(id=suggestion.id) new_instance = models.FermentableInstance.objects.get(id=suggestion.suggested_object_id) new_instance_data = serializers.FermentableInstance(new_instance).data data = { "fermentable_id": new_instance.fermentable_id, "old_instance_id": suggestion.replaced_object_id, "new_instance": new_instance_data } return Response(data) else: return Response(serializer.errors) def update(self, request, pk=None): """Allows admins to update specific fermentable instance objects.""" instance = get_object_or_404(models.FermentableInstance, pk=pk) serializer = serializers.FermentableInstance(data=request.data) if serializer.is_valid(): instance = serializer.save() if request.data['is_active'] is not None: instance.is_active = request.data['is_active'] instance.save() return Response(serializer.data) else: return Response(serializer.errors) class Fermentables(viewsets.ViewSet): """ View to Retrieve all approved fermentables and Suggest new fermentables. """ authentication_classes = (JSONWebTokenAuthentication, TokenAuthentication) def get_permissions(self): """Define custom permissions for different methods""" # at minimum require users to be authenticated self.permission_classes = [IsAuthenticated] # for PUT requests require users to be admins if self.request.method == 'PUT': self.permission_classes.append(IsAdminUser) return super(viewsets.ViewSet, self).get_permissions() def list(self, request): """ Returns all fermentables that are approved in the system by default. """ fermentables = models.Fermentable.objects.filter(is_active=True) if request.auth is None: fermentables = fermentables[:settings.UNAUTHENTICATED_RESULTS_COUNT] serializer = rf_serializers.ListSerializer( fermentables, child=serializers.Fermentable() ) return Response(serializer.data) def create(self, request): """ Create a new suggestion for a fermentable. """ serializer = serializers.FermentableSuggestion(data=request.data) if serializer.is_valid(): suggestion = serializer.save() suggestion = models.Suggestion.objects.get(id=suggestion.id) new_fermentable = models.Fermentable.objects.get(id=suggestion.suggested_object_id) new_fermentable_data = serializers.Fermentable(new_fermentable).data data = { "old_fermentable_id": suggestion.replaced_object_id, "new_fermentable": new_fermentable_data } return Response(data) else: return Response(serializer.errors) def update(self, request, pk=None): """Allows admins to update specific fermentable objects.""" fermentable = get_object_or_404(models.Fermentable, pk=pk) serializer = serializers.SimpleFermentable(data=request.data) if serializer.is_valid(): fermentable = serializer.save() if request.data['is_active'] is not None: fermentable.is_active = request.data['is_active'] fermentable.save() return Response(serializer.data) else: return Response(serializer.errors)