191 lines
7.2 KiB
Python
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)
|