nabilah_argyanti_ardyningrum/backend/easycookapi-main/recipes/views.py
2024-12-31 09:49:01 +07:00

191 lines
7.2 KiB
Python

from recipes.models import Information, Review, RawIngredient, Unit
from profiles.models import Pantry
from rest_framework import generics, status, permissions
from rest_framework.response import Response
from .serializers import (
RecipeInformationSerializer,
ReviewSerializer,
RecipeDetailSerializer,
RecipeIngredientsSerializer,
RawIngredientSerializer,
UnitSerializer
)
from .models import Ingredient
from django.http import JsonResponse
class IsAuthenticatedOrReadOnly(permissions.BasePermission):
def has_permission(self, request, view):
if request.method == 'GET' or request.user.is_authenticated:
return True
return False
class RecipeListView(generics.GenericAPIView):
serializer_class = RecipeInformationSerializer
def get(self, request):
recipes = Information.objects.all()[:30]
recipes_serializer = self.serializer_class(
recipes, context={'request': request}, many=True)
return Response(recipes_serializer.data)
class OwnedIngredientView(generics.GenericAPIView):
serializer_class = RecipeIngredientsSerializer
def get(self, request, recipe_id):
user = request.user
if not user.is_authenticated:
return Response([])
owned_raw_ingredient_ids = Pantry.objects.filter(
user=user).values_list('raw_ingredient_id', flat=True)
owned_ingredients = Ingredient.objects.filter(
raw_ingredient__in=owned_raw_ingredient_ids, recipe_id=recipe_id).distinct()
serializer = RecipeIngredientsSerializer(owned_ingredients, many=True)
return Response(serializer.data)
class NotOwnedIngredientViews(generics.GenericAPIView):
serializer_class = RecipeIngredientsSerializer
def get(self, request, recipe_id):
user = request.user
if not user.is_authenticated:
all_ingredients = Ingredient.objects.filter(recipe_id=recipe_id)
serializer = RecipeIngredientsSerializer(
all_ingredients, many=True)
return Response(serializer.data)
owned_raw_ingredient_ids = Pantry.objects.filter(
user=user).values_list('raw_ingredient_id', flat=True)
not_owned_ingredients = Ingredient.objects.filter(
recipe_id=recipe_id).exclude(raw_ingredient__in=owned_raw_ingredient_ids)
serializer = RecipeIngredientsSerializer(
not_owned_ingredients, many=True)
return Response(serializer.data)
class RecipeDetailView(generics.GenericAPIView):
serializer_class = RecipeDetailSerializer
permission_classes = [permissions.AllowAny]
def get(self, request, recipe_id):
recipes = Information.objects.get(pk=recipe_id)
recipes_serializer = self.serializer_class(
recipes, context={'request': request})
return Response(recipes_serializer.data)
class SearchRecipeView(generics.GenericAPIView):
def get(self, request):
keyword = request.GET.get('keyword')
if not keyword or not keyword.strip():
return Response({'message': 'Kata kunci yang Anda masukkan tidak valid'}, status=status.HTTP_400_BAD_REQUEST)
recipes = Information.objects.filter(title__icontains=keyword)
if not recipes:
return Response({'message': 'Resep tidak ditemukan'}, status=status.HTTP_404_NOT_FOUND)
recipes_list = RecipeInformationSerializer(
recipes, context={'request': request}, many=True).data
sorted_recipes = sorted(
recipes_list, key=lambda x: x['completeness_percentage'], reverse=True)
return Response(sorted_recipes, status=status.HTTP_200_OK)
class ReviewView(generics.GenericAPIView):
permission_classes = [IsAuthenticatedOrReadOnly]
serializer_class = ReviewSerializer
def get(self, request, recipe_id, review_id=None):
if review_id is not None:
try:
review = Review.objects.get(
recipe_id=recipe_id, pk=review_id, user=request.user)
except Review.DoesNotExist:
return Response({"message": "Ulasan tidak ditemukan"}, status=status.HTTP_404_NOT_FOUND)
review_serializer = self.serializer_class(review)
return Response(review_serializer.data)
else:
reviews = Review.objects.filter(recipe_id=recipe_id)
if not reviews:
return Response({"message": "Tidak ada ulasan"}, status=status.HTTP_404_NOT_FOUND)
review_serializer = self.serializer_class(reviews, many=True)
return Response(review_serializer.data)
def post(self, request, recipe_id):
try:
recipe = Information.objects.get(pk=recipe_id)
except Information.DoesNotExist:
return JsonResponse({'message': 'Resep tidak ditemukan'}, status=status.HTTP_404_NOT_FOUND)
review_serializer = self.serializer_class(data=request.data)
if Review.objects.filter(user=request.user, recipe=recipe).exists():
return Response({'message': 'Anda sudah memberikan ulasan'}, status=status.HTTP_400_BAD_REQUEST)
if review_serializer.is_valid():
saved_review = review_serializer.save(
user=request.user, recipe=recipe)
return Response(self.serializer_class(saved_review).data, status=status.HTTP_201_CREATED)
return Response(review_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def put(self, request, recipe_id, review_id):
review = Review.objects.get(
pk=review_id, user=request.user, recipe_id=recipe_id)
if not review:
return Response({"message": "Ulasan tidak ditemukan"}, status=status.HTTP_404_NOT_FOUND)
review_serializer = self.serializer_class(
instance=review, data=request.data)
if review_serializer.is_valid():
review_serializer.save()
return Response(review_serializer.data)
else:
return Response(review_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, recipe_id, review_id):
try:
review = Review.objects.get(
pk=review_id, user=request.user)
review.delete()
return Response({'message': 'Berhasil menghapus ulasan'}, status=status.HTTP_200_OK)
except Review.DoesNotExist:
return Response({'message': 'Ulasan tidak ditemukan'}, status=status.HTTP_404_NOT_FOUND)
class RawIngredientView(generics.GenericAPIView):
serializer_class = RawIngredientSerializer
def get(self, request):
if request.GET.get('name'):
raw_materials = RawIngredient.objects.filter(
name__icontains=request.GET.get('name'))
else:
raw_materials = RawIngredient.objects.all()
serializer = self.get_serializer(raw_materials, many=True)
return Response(serializer.data)
class UnitView(generics.GenericAPIView):
def get(self, request):
raw_ingredient_id = request.GET.get('raw_ingredient_id')
units = Unit.objects.filter(
ingredient__raw_ingredient_id=raw_ingredient_id).distinct()
units_list = UnitSerializer(units, many=True).data
return Response(units_list, status=status.HTTP_200_OK)