From 42214ad8968c7a8fc99741feebf495e60b248cc1 Mon Sep 17 00:00:00 2001 From: dazfz Date: Wed, 6 Sep 2023 22:57:12 -0300 Subject: [PATCH 1/3] implement get by: id, name, type and hp --- pokemon/serializers.py | 22 +++++++++-- pokemon/views.py | 85 +++++++++++++++++++++++++++++++++++------- 2 files changed, 91 insertions(+), 16 deletions(-) diff --git a/pokemon/serializers.py b/pokemon/serializers.py index 2148325..8139cab 100644 --- a/pokemon/serializers.py +++ b/pokemon/serializers.py @@ -2,12 +2,28 @@ from pokemon.models import Pokemon, PokemonTypes -# TODO: Add a serializer for PokemonTypes, and use it as a nested serializer for PokemonSerializer +class TypeSerializer(serializers.ModelSerializer): + class Meta: + model = PokemonTypes + fields = ("type",) class PokemonSerializer(serializers.ModelSerializer): + types = TypeSerializer(many=True) class Meta: model = Pokemon - fields = ('id', 'name_english', 'name_japanese', 'name_chinese', 'name_french', 'hp', 'attack', 'defense', - 'special_attack', 'special_defense', 'speed', ) + fields = ( + "id", + "name_english", + "name_japanese", + "name_chinese", + "name_french", + "hp", + "attack", + "defense", + "special_attack", + "special_defense", + "speed", + "types", + ) diff --git a/pokemon/views.py b/pokemon/views.py index d7ef66b..ecc4ce9 100644 --- a/pokemon/views.py +++ b/pokemon/views.py @@ -1,40 +1,52 @@ -from django.http import JsonResponse, HttpResponse +from django.http import JsonResponse +from django.shortcuts import get_object_or_404 from django.views.decorators.csrf import csrf_exempt from rest_framework.decorators import api_view +from django.db.models import Q from pokemon.models import Pokemon, VALID_POKEMON_TYPES from pokemon.serializers import PokemonSerializer @csrf_exempt -@api_view(['GET']) +@api_view(["GET"]) def pokemon_list(request): """ List all Pokemon """ pokemon = Pokemon.objects.all() serializer = PokemonSerializer(pokemon, many=True) - return JsonResponse(serializer.data, safe=False, json_dumps_params={'ensure_ascii': False}) + return JsonResponse( + serializer.data, safe=False, json_dumps_params={"ensure_ascii": False} + ) @csrf_exempt -@api_view(['GET']) +@api_view(["GET"]) def pokemon_by_id(request, id): """ Get Pokemon by ID """ - # TODO: Implement Endpoint - return HttpResponse(status=501) + try: + pokemon = get_object_or_404(Pokemon, id=id) + serializer = PokemonSerializer(pokemon) + return JsonResponse(serializer.data, safe=False) + except Pokemon.DoesNotExist: + return JsonResponse({"error": "Not found"}, status=404) @csrf_exempt -@api_view(['GET']) +@api_view(["GET"]) def pokemon_by_name(request, name): """ Get Pokemon by name """ - # TODO: Implement Endpoint - return HttpResponse(status=501) + try: + pokemon = get_object_or_404(Pokemon, name_english__iexact=name) + serializer = PokemonSerializer(pokemon) + return JsonResponse(serializer.data, safe=False) + except Pokemon.DoesNotExist: + return JsonResponse({"error": "Not found"}, status=404) @csrf_exempt @@ -42,8 +54,16 @@ def pokemon_by_type(request, pokemon_type): """ Get Pokemon by type """ - # TODO: Implement Endpoint - return HttpResponse(status=501) + try: + # check if type exists + if pokemon_type.lower() not in [t[0].lower() for t in VALID_POKEMON_TYPES]: + return JsonResponse({"error": "Bad Request"}, status=400) + + pokemon = Pokemon.objects.filter(types__type__iexact=pokemon_type) + serializer = PokemonSerializer(pokemon, many=True) + return JsonResponse(serializer.data, safe=False) + except Pokemon.DoesNotExist: + return JsonResponse({"error": "Not found"}, status=404) @csrf_exempt @@ -51,5 +71,44 @@ def pokemon_by_hp(request): """ Get Pokemon by HP """ - # TODO: Implement Endpoint - return HttpResponse(status=501) + + VALID_COMPARATORS = ["gt", "gte", "lt", "lte"] + + try: + comparators = [ + comparator + for comparator in VALID_COMPARATORS + if request.GET.get(comparator) + ] + + if not comparators: + return JsonResponse( + { + "error": 'Invalid Operator. Must be one of ["gt", "gte", "lt", "lte"]' + }, + status=400, + ) + + # Initialize the filter with Q objects based on the selected comparators + filter_query = Q() + for comparator in comparators: + value = int(request.GET.get(comparator)) + if comparator == "gt": + filter_query &= Q(hp__gt=value) + elif comparator == "gte": + filter_query &= Q(hp__gte=value) + elif comparator == "lt": + filter_query &= Q(hp__lt=value) + elif comparator == "lte": + filter_query &= Q(hp__lte=value) + + pokemons = Pokemon.objects.filter(filter_query) + serializer = PokemonSerializer(pokemons, many=True) + + if pokemons.exists(): + return JsonResponse(serializer.data, safe=False) + else: + return JsonResponse({"error": "Not found"}, status=404) + + except Pokemon.DoesNotExist: + return JsonResponse({"error": "Not found"}, status=404) From 1ef1aa1da3a003625accf54b2ad9d59c1c4b8f75 Mon Sep 17 00:00:00 2001 From: dazfz Date: Thu, 7 Sep 2023 11:06:20 -0300 Subject: [PATCH 2/3] fix error using http404 --- pokemon/views.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pokemon/views.py b/pokemon/views.py index ecc4ce9..ee7bdef 100644 --- a/pokemon/views.py +++ b/pokemon/views.py @@ -1,4 +1,4 @@ -from django.http import JsonResponse +from django.http import Http404, JsonResponse from django.shortcuts import get_object_or_404 from django.views.decorators.csrf import csrf_exempt from rest_framework.decorators import api_view @@ -31,7 +31,7 @@ def pokemon_by_id(request, id): pokemon = get_object_or_404(Pokemon, id=id) serializer = PokemonSerializer(pokemon) return JsonResponse(serializer.data, safe=False) - except Pokemon.DoesNotExist: + except Http404: return JsonResponse({"error": "Not found"}, status=404) @@ -45,7 +45,7 @@ def pokemon_by_name(request, name): pokemon = get_object_or_404(Pokemon, name_english__iexact=name) serializer = PokemonSerializer(pokemon) return JsonResponse(serializer.data, safe=False) - except Pokemon.DoesNotExist: + except Http404: return JsonResponse({"error": "Not found"}, status=404) @@ -62,7 +62,7 @@ def pokemon_by_type(request, pokemon_type): pokemon = Pokemon.objects.filter(types__type__iexact=pokemon_type) serializer = PokemonSerializer(pokemon, many=True) return JsonResponse(serializer.data, safe=False) - except Pokemon.DoesNotExist: + except Http404: return JsonResponse({"error": "Not found"}, status=404) @@ -104,11 +104,11 @@ def pokemon_by_hp(request): pokemons = Pokemon.objects.filter(filter_query) serializer = PokemonSerializer(pokemons, many=True) - + if pokemons.exists(): return JsonResponse(serializer.data, safe=False) else: return JsonResponse({"error": "Not found"}, status=404) - except Pokemon.DoesNotExist: + except Http404: return JsonResponse({"error": "Not found"}, status=404) From 76b15f97f212375552e2d81693d092e4824a8a8b Mon Sep 17 00:00:00 2001 From: dazfz Date: Thu, 7 Sep 2023 11:11:52 -0300 Subject: [PATCH 3/3] fix typos --- pokemon/views.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pokemon/views.py b/pokemon/views.py index ee7bdef..2a406d8 100644 --- a/pokemon/views.py +++ b/pokemon/views.py @@ -57,7 +57,7 @@ def pokemon_by_type(request, pokemon_type): try: # check if type exists if pokemon_type.lower() not in [t[0].lower() for t in VALID_POKEMON_TYPES]: - return JsonResponse({"error": "Bad Request"}, status=400) + return JsonResponse({"error": "Bad request"}, status=400) pokemon = Pokemon.objects.filter(types__type__iexact=pokemon_type) serializer = PokemonSerializer(pokemon, many=True) @@ -83,9 +83,7 @@ def pokemon_by_hp(request): if not comparators: return JsonResponse( - { - "error": 'Invalid Operator. Must be one of ["gt", "gte", "lt", "lte"]' - }, + {"error": 'Invalid Operator. Must be one of ["gt","gte","lt","lte"]'}, status=400, )