mirror of
https://github.com/PokeAPI/pokeapi
synced 2024-11-24 20:33:04 +00:00
4180 lines
145 KiB
Python
4180 lines
145 KiB
Python
from collections import OrderedDict
|
|
import json
|
|
from django.urls import reverse
|
|
from rest_framework import serializers
|
|
from drf_spectacular.types import OpenApiTypes
|
|
from drf_spectacular.utils import extend_schema_field, extend_schema, OpenApiParameter, OpenApiExample, extend_schema_serializer
|
|
|
|
# pylint: disable=redefined-builtin
|
|
|
|
# PokeAPI v2 serializers in order of dependency
|
|
|
|
from .models import *
|
|
|
|
|
|
#########################
|
|
# SUMMARY SERIALIZERS #
|
|
#########################
|
|
|
|
# Summary serializers are just for list and reference behavior
|
|
|
|
# Putting summary serializers up top so there are no conflicts
|
|
# with reference accross models due to script running order
|
|
|
|
|
|
class AbilitySummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = Ability
|
|
fields = ("name", "url")
|
|
|
|
|
|
class BerryFirmnessSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = BerryFirmness
|
|
fields = ("name", "url")
|
|
|
|
|
|
class BerryFlavorSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = BerryFlavor
|
|
fields = ("name", "url")
|
|
|
|
|
|
class BerrySummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = Berry
|
|
fields = ("name", "url")
|
|
|
|
|
|
class CharacteristicSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = Characteristic
|
|
fields = ("url",)
|
|
|
|
|
|
class ContestEffectSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = ContestEffect
|
|
fields = ("url",)
|
|
|
|
|
|
class ContestTypeSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = ContestType
|
|
fields = ("name", "url")
|
|
|
|
|
|
class EggGroupSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = EggGroup
|
|
fields = ("name", "url")
|
|
|
|
|
|
class EncounterConditionSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = EncounterCondition
|
|
fields = ("name", "url")
|
|
|
|
|
|
class EncounterConditionValueSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = EncounterConditionValue
|
|
fields = ("name", "url")
|
|
|
|
|
|
class EncounterMethodSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = EncounterMethod
|
|
fields = ("name", "url")
|
|
|
|
|
|
class EvolutionTriggerSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = EvolutionTrigger
|
|
fields = ("name", "url")
|
|
|
|
|
|
class EvolutionChainSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = EvolutionChain
|
|
fields = ("url",)
|
|
|
|
|
|
class GenerationSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = Generation
|
|
fields = ("name", "url")
|
|
|
|
|
|
class GenderSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = Gender
|
|
fields = ("name", "url")
|
|
|
|
|
|
class GrowthRateSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = GrowthRate
|
|
fields = ("name", "url")
|
|
|
|
|
|
class ItemPocketSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = ItemPocket
|
|
fields = ("name", "url")
|
|
|
|
|
|
class ItemCategorySummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = ItemCategory
|
|
fields = ("name", "url")
|
|
|
|
|
|
class ItemAttributeSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = ItemAttribute
|
|
fields = ("name", "url")
|
|
|
|
|
|
class ItemFlingEffectSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = ItemFlingEffect
|
|
fields = ("name", "url")
|
|
|
|
|
|
class ItemSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = Item
|
|
fields = ("name", "url")
|
|
|
|
|
|
class LanguageSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = Language
|
|
fields = ("name", "url")
|
|
|
|
|
|
class LocationSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = Location
|
|
fields = ("name", "url")
|
|
|
|
|
|
class LocationAreaSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = LocationArea
|
|
fields = ("name", "url")
|
|
|
|
|
|
class MachineSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = Machine
|
|
fields = ("url",)
|
|
|
|
|
|
class MoveBattleStyleSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = MoveBattleStyle
|
|
fields = ("name", "url")
|
|
|
|
|
|
class MoveDamageClassSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = MoveDamageClass
|
|
fields = ("name", "url")
|
|
|
|
|
|
class MoveMetaAilmentSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = MoveMetaAilment
|
|
fields = ("name", "url")
|
|
|
|
|
|
class MoveMetaCategorySummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = MoveMetaCategory
|
|
fields = ("name", "url")
|
|
|
|
|
|
class MoveTargetSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = MoveTarget
|
|
fields = ("name", "url")
|
|
|
|
|
|
class MoveSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = Move
|
|
fields = ("name", "url")
|
|
|
|
|
|
class MoveLearnMethodSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = MoveLearnMethod
|
|
fields = ("name", "url")
|
|
|
|
|
|
class NatureSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = Nature
|
|
fields = ("name", "url")
|
|
|
|
|
|
class PalParkAreaSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = PalParkArea
|
|
fields = ("name", "url")
|
|
|
|
|
|
class PokeathlonStatSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = PokeathlonStat
|
|
fields = ("name", "url")
|
|
|
|
|
|
class PokedexSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = Pokedex
|
|
fields = ("name", "url")
|
|
|
|
|
|
class PokemonColorSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = PokemonColor
|
|
fields = ("name", "url")
|
|
|
|
|
|
class PokemonHabitatSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = PokemonHabitat
|
|
fields = ("name", "url")
|
|
|
|
|
|
class PokemonShapeSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = PokemonShape
|
|
fields = ("name", "url")
|
|
|
|
|
|
class PokemonSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = Pokemon
|
|
fields = ("name", "url")
|
|
|
|
|
|
class PokemonSpeciesSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = PokemonSpecies
|
|
fields = ("name", "url")
|
|
|
|
|
|
class PokemonFormSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = PokemonForm
|
|
fields = ("name", "url")
|
|
|
|
|
|
class RegionSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = Region
|
|
fields = ("name", "url")
|
|
|
|
|
|
class StatSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = Stat
|
|
fields = ("name", "url")
|
|
|
|
|
|
class SuperContestEffectSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = SuperContestEffect
|
|
fields = ("url",)
|
|
|
|
|
|
class TypeSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = Type
|
|
fields = ("name", "url")
|
|
|
|
|
|
class VersionSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = Version
|
|
fields = ("name", "url")
|
|
|
|
|
|
class VersionGroupSummarySerializer(serializers.HyperlinkedModelSerializer):
|
|
class Meta:
|
|
model = VersionGroup
|
|
fields = ("name", "url")
|
|
|
|
|
|
#####################
|
|
# MAP SERIALIZERS #
|
|
#####################
|
|
|
|
|
|
class BerryFlavorMapSerializer(serializers.ModelSerializer):
|
|
berry = BerrySummarySerializer()
|
|
flavor = BerryFlavorSummarySerializer(source="berry_flavor")
|
|
|
|
class Meta:
|
|
model = BerryFlavorMap
|
|
fields = ("potency", "berry", "flavor")
|
|
|
|
|
|
class ItemAttributeMapSerializer(serializers.ModelSerializer):
|
|
item = ItemSummarySerializer()
|
|
attribute = ItemAttributeSummarySerializer(source="item_attribute")
|
|
|
|
class Meta:
|
|
model = ItemAttributeMap
|
|
fields = (
|
|
"item",
|
|
"attribute",
|
|
)
|
|
|
|
|
|
class MoveMetaStatChangeSerializer(serializers.ModelSerializer):
|
|
stat = StatSummarySerializer()
|
|
move = MoveSummarySerializer()
|
|
|
|
class Meta:
|
|
model = MoveMetaStatChange
|
|
fields = ("change", "move", "stat")
|
|
|
|
|
|
class NaturePokeathlonStatSerializer(serializers.ModelSerializer):
|
|
pokeathlon_stat = PokeathlonStatSummarySerializer()
|
|
nature = NatureSummarySerializer()
|
|
|
|
class Meta:
|
|
model = NaturePokeathlonStat
|
|
fields = ("max_change", "nature", "pokeathlon_stat")
|
|
|
|
|
|
class PokemonAbilitySerializer(serializers.ModelSerializer):
|
|
pokemon = PokemonSummarySerializer()
|
|
ability = AbilitySummarySerializer()
|
|
|
|
class Meta:
|
|
model = PokemonAbility
|
|
fields = ("is_hidden", "slot", "ability", "pokemon")
|
|
|
|
|
|
class PokemonAbilityPastSerializer(serializers.ModelSerializer):
|
|
generation = GenerationSummarySerializer()
|
|
ability = AbilitySummarySerializer()
|
|
|
|
class Meta:
|
|
model = PokemonAbilityPast
|
|
fields = ("is_hidden", "pokemon", "generation", "slot", "ability")
|
|
|
|
|
|
class PokemonDexEntrySerializer(serializers.ModelSerializer):
|
|
entry_number = serializers.IntegerField(source="pokedex_number")
|
|
pokedex = PokedexSummarySerializer()
|
|
|
|
class Meta:
|
|
model = PokemonDexNumber
|
|
fields = ("entry_number", "pokedex")
|
|
|
|
|
|
class PokemonTypeSerializer(serializers.ModelSerializer):
|
|
pokemon = PokemonSummarySerializer()
|
|
type = TypeSummarySerializer()
|
|
|
|
class Meta:
|
|
model = PokemonType
|
|
fields = ("slot", "pokemon", "type")
|
|
|
|
|
|
class PokemonFormTypeSerializer(serializers.ModelSerializer):
|
|
pokemon_form = PokemonFormSummarySerializer()
|
|
type = TypeSummarySerializer()
|
|
|
|
class Meta:
|
|
model = PokemonFormType
|
|
fields = ("slot", "pokemon_form", "type")
|
|
|
|
|
|
class PokemonTypePastSerializer(serializers.ModelSerializer):
|
|
generation = GenerationSummarySerializer()
|
|
type = TypeSummarySerializer()
|
|
|
|
class Meta:
|
|
model = PokemonTypePast
|
|
fields = ("pokemon", "generation", "slot", "type")
|
|
|
|
|
|
class PokedexVersionGroupSerializer(serializers.ModelSerializer):
|
|
pokedex = PokedexSummarySerializer()
|
|
version_group = VersionGroupSummarySerializer()
|
|
|
|
class Meta:
|
|
model = PokedexVersionGroup
|
|
fields = ("pokedex", "version_group")
|
|
|
|
|
|
class VersionGroupMoveLearnMethodSerializer(serializers.ModelSerializer):
|
|
version_group = VersionGroupSummarySerializer()
|
|
move_learn_method = MoveLearnMethodSummarySerializer()
|
|
|
|
class Meta:
|
|
model = ItemAttributeMap
|
|
fields = ("version_group", "move_learn_method")
|
|
|
|
|
|
class VersionGroupRegionSerializer(serializers.ModelSerializer):
|
|
version_group = VersionGroupSummarySerializer()
|
|
region = RegionSummarySerializer()
|
|
|
|
class Meta:
|
|
model = ItemAttributeMap
|
|
fields = (
|
|
"version_group",
|
|
"region",
|
|
)
|
|
|
|
|
|
class EncounterConditionValueMapSerializer(serializers.ModelSerializer):
|
|
condition_value = EncounterConditionValueSummarySerializer(
|
|
source="encounter_condition_value"
|
|
)
|
|
|
|
class Meta:
|
|
model = EncounterConditionValueMap
|
|
fields = ("condition_value",)
|
|
|
|
|
|
################################
|
|
# CHARACTERISTIC SERIALIZERS #
|
|
################################
|
|
|
|
|
|
class CharacteristicDescriptionSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = CharacteristicDescription
|
|
fields = ("description", "language")
|
|
|
|
|
|
class CharacteristicDetailSerializer(serializers.ModelSerializer):
|
|
descriptions = CharacteristicDescriptionSerializer(
|
|
many=True, read_only=True, source="characteristicdescription"
|
|
)
|
|
highest_stat = StatSummarySerializer(source="stat")
|
|
gene_modulo = serializers.IntegerField(source="gene_mod_5")
|
|
possible_values = serializers.SerializerMethodField("get_values")
|
|
|
|
class Meta:
|
|
model = Characteristic
|
|
fields = (
|
|
"id",
|
|
"gene_modulo",
|
|
"possible_values",
|
|
"highest_stat",
|
|
"descriptions",
|
|
)
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_values(self, obj):
|
|
mod = obj.gene_mod_5
|
|
values = []
|
|
while mod <= 31:
|
|
values.append(mod)
|
|
mod += 5
|
|
|
|
return values
|
|
|
|
|
|
#########################
|
|
# CONTEST SERIALIZERS #
|
|
#########################
|
|
|
|
|
|
class SuperContestEffectFlavorTextSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = SuperContestEffectFlavorText
|
|
fields = ("flavor_text", "language")
|
|
|
|
|
|
class SuperContestEffectDetailSerializer(serializers.ModelSerializer):
|
|
flavor_text_entries = SuperContestEffectFlavorTextSerializer(
|
|
many=True, read_only=True, source="supercontesteffectflavortext"
|
|
)
|
|
moves = MoveSummarySerializer(many=True, read_only=True, source="move")
|
|
|
|
class Meta:
|
|
model = SuperContestEffect
|
|
fields = ("id", "appeal", "flavor_text_entries", "moves")
|
|
|
|
|
|
class ContestEffectEffectTextSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = ContestEffectEffectText
|
|
fields = ("effect", "language")
|
|
|
|
|
|
class ContestEffectFlavorTextSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = ContestEffectFlavorText
|
|
fields = ("flavor_text", "language")
|
|
|
|
|
|
class ContestEffectDetailSerializer(serializers.ModelSerializer):
|
|
effect_entries = ContestEffectEffectTextSerializer(
|
|
many=True, read_only=True, source="contesteffecteffecttext"
|
|
)
|
|
flavor_text_entries = ContestEffectFlavorTextSerializer(
|
|
many=True, read_only=True, source="contesteffectflavortext"
|
|
)
|
|
|
|
class Meta:
|
|
model = ContestEffect
|
|
fields = ("id", "appeal", "jam", "effect_entries", "flavor_text_entries")
|
|
|
|
|
|
class ContestTypeNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = ContestTypeName
|
|
fields = ("name", "color", "language")
|
|
|
|
|
|
class ContestTypeDetailSerializer(serializers.ModelSerializer):
|
|
names = ContestTypeNameSerializer(
|
|
many=True, read_only=True, source="contesttypename"
|
|
)
|
|
berry_flavor = BerryFlavorSummarySerializer(read_only=True, source="berryflavor")
|
|
|
|
class Meta:
|
|
model = ContestType
|
|
fields = ("id", "name", "berry_flavor", "names")
|
|
|
|
|
|
class SuperContestComboSerializer(serializers.ModelSerializer):
|
|
first_move = MoveSummarySerializer()
|
|
second_move = MoveSummarySerializer()
|
|
|
|
class Meta:
|
|
model = SuperContestCombo
|
|
fields = ("first_move", "second_move")
|
|
|
|
|
|
class ContestComboSerializer(serializers.ModelSerializer):
|
|
first_move = MoveSummarySerializer()
|
|
second_move = MoveSummarySerializer()
|
|
|
|
class Meta:
|
|
model = ContestCombo
|
|
fields = ("first_move", "second_move")
|
|
|
|
|
|
########################
|
|
# REGION SERIALIZERS #
|
|
########################
|
|
|
|
|
|
class RegionNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = RegionName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class RegionDetailSerializer(serializers.ModelSerializer):
|
|
names = RegionNameSerializer(many=True, read_only=True, source="regionname")
|
|
locations = LocationSummarySerializer(many=True, read_only=True, source="location")
|
|
version_groups = serializers.SerializerMethodField("get_region_version_groups")
|
|
pokedexes = PokedexSummarySerializer(many=True, read_only=True, source="pokedex")
|
|
main_generation = GenerationSummarySerializer(read_only=True, source="generation")
|
|
|
|
class Meta:
|
|
model = Region
|
|
fields = (
|
|
"id",
|
|
"name",
|
|
"locations",
|
|
"main_generation",
|
|
"names",
|
|
"pokedexes",
|
|
"version_groups",
|
|
)
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_region_version_groups(self, obj):
|
|
vg_regions = VersionGroupRegion.objects.filter(region=obj)
|
|
data = VersionGroupRegionSerializer(
|
|
vg_regions, many=True, context=self.context
|
|
).data
|
|
groups = []
|
|
|
|
for group in data:
|
|
groups.append(group["version_group"])
|
|
|
|
return groups
|
|
|
|
|
|
############################
|
|
# GENERATION SERIALIZERS #
|
|
############################
|
|
|
|
|
|
class GenerationNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = GenerationName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class GenerationDetailSerializer(serializers.ModelSerializer):
|
|
main_region = RegionSummarySerializer(source="region")
|
|
names = GenerationNameSerializer(many=True, read_only=True, source="generationname")
|
|
abilities = AbilitySummarySerializer(many=True, read_only=True, source="ability")
|
|
moves = MoveSummarySerializer(many=True, read_only=True, source="move")
|
|
pokemon_species = PokemonSpeciesSummarySerializer(
|
|
many=True, read_only=True, source="pokemonspecies"
|
|
)
|
|
types = TypeSummarySerializer(many=True, read_only=True, source="type")
|
|
version_groups = VersionGroupSummarySerializer(
|
|
many=True, read_only=True, source="versiongroup"
|
|
)
|
|
|
|
class Meta:
|
|
model = Generation
|
|
fields = (
|
|
"id",
|
|
"name",
|
|
"abilities",
|
|
"main_region",
|
|
"moves",
|
|
"names",
|
|
"pokemon_species",
|
|
"types",
|
|
"version_groups",
|
|
)
|
|
|
|
|
|
########################
|
|
# GENDER SERIALIZERS #
|
|
########################
|
|
|
|
|
|
class GenderDetailSerializer(serializers.ModelSerializer):
|
|
pokemon_species_details = serializers.SerializerMethodField("get_species")
|
|
required_for_evolution = serializers.SerializerMethodField("get_required")
|
|
|
|
class Meta:
|
|
model = Gender
|
|
fields = ("id", "name", "pokemon_species_details", "required_for_evolution")
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_species(self, obj):
|
|
species_objects = []
|
|
|
|
if obj.name == "female":
|
|
species_objects = PokemonSpecies.objects.filter(gender_rate__gt=0)
|
|
elif obj.name == "male":
|
|
species_objects = PokemonSpecies.objects.filter(gender_rate__range=[0, 7])
|
|
elif obj.name == "genderless":
|
|
species_objects = PokemonSpecies.objects.filter(gender_rate=-1)
|
|
|
|
details = []
|
|
|
|
for species in species_objects:
|
|
detail = OrderedDict()
|
|
detail["rate"] = species.gender_rate
|
|
detail["pokemon_species"] = PokemonSpeciesSummarySerializer(
|
|
species, context=self.context
|
|
).data
|
|
details.append(detail)
|
|
|
|
return details
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_required(self, obj):
|
|
evo_objects = PokemonEvolution.objects.filter(gender=obj)
|
|
species_list = []
|
|
|
|
for evo in evo_objects:
|
|
species = PokemonSpeciesSummarySerializer(
|
|
evo.evolved_species, context=self.context
|
|
).data
|
|
species_list.append(species)
|
|
|
|
return species_list
|
|
|
|
|
|
#############################
|
|
# GROWTH RATE SERIALIZERS #
|
|
#############################
|
|
|
|
|
|
class ExperienceSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Experience
|
|
fields = ("level", "experience")
|
|
|
|
|
|
class GrowthRateDescriptionSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = GrowthRateDescription
|
|
fields = ("description", "language")
|
|
|
|
|
|
class GrowthRateDetailSerializer(serializers.ModelSerializer):
|
|
descriptions = GrowthRateDescriptionSerializer(
|
|
many=True, read_only=True, source="growthratedescription"
|
|
)
|
|
levels = ExperienceSerializer(many=True, read_only=True, source="experience")
|
|
pokemon_species = PokemonSpeciesSummarySerializer(
|
|
many=True, read_only=True, source="pokemonspecies"
|
|
)
|
|
|
|
class Meta:
|
|
model = GrowthRate
|
|
fields = ("id", "name", "formula", "descriptions", "levels", "pokemon_species")
|
|
|
|
|
|
##########################
|
|
# LANGUAGE SERIALIZERS #
|
|
##########################
|
|
|
|
|
|
class LanguageNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer(source="local_language")
|
|
|
|
class Meta:
|
|
model = LanguageName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class LanguageDetailSerializer(serializers.ModelSerializer):
|
|
names = LanguageNameSerializer(
|
|
many=True, read_only=True, source="languagename_language"
|
|
)
|
|
|
|
class Meta:
|
|
model = Language
|
|
fields = ("id", "name", "official", "iso639", "iso3166", "names")
|
|
|
|
|
|
########################################
|
|
# LOCATION AND ENCOUNTER SERIALIZERS #
|
|
########################################
|
|
|
|
|
|
class EncounterConditionNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = EncounterConditionName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class EncounterConditionDetailSerializer(serializers.ModelSerializer):
|
|
names = EncounterConditionNameSerializer(
|
|
many=True, read_only=True, source="encounterconditionname"
|
|
)
|
|
values = EncounterConditionValueSummarySerializer(
|
|
many=True, read_only=True, source="encounterconditionvalue"
|
|
)
|
|
|
|
class Meta:
|
|
model = EncounterCondition
|
|
fields = ("id", "name", "values", "names")
|
|
|
|
|
|
class EncounterConditionValueNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = EncounterConditionValueName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class EncounterConditionValueDetailSerializer(serializers.ModelSerializer):
|
|
condition = EncounterConditionSummarySerializer(source="encounter_condition")
|
|
names = EncounterConditionValueNameSerializer(
|
|
many=True, read_only=True, source="encounterconditionvaluename"
|
|
)
|
|
|
|
class Meta:
|
|
model = EncounterConditionValue
|
|
fields = ("id", "name", "condition", "names")
|
|
|
|
|
|
class EncounterMethodNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = EncounterMethodName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class EncounterMethodDetailSerializer(serializers.ModelSerializer):
|
|
names = EncounterMethodNameSerializer(
|
|
many=True, read_only=True, source="encountermethodname"
|
|
)
|
|
|
|
class Meta:
|
|
model = EncounterMethod
|
|
fields = ("id", "name", "order", "names")
|
|
|
|
|
|
class EncounterSlotSerializer(serializers.ModelSerializer):
|
|
encounter_method = EncounterMethodSummarySerializer()
|
|
chance = serializers.IntegerField(source="rarity")
|
|
|
|
class Meta:
|
|
model = EncounterSlot
|
|
fields = ("id", "slot", "chance", "encounter_method", "version_group")
|
|
|
|
|
|
class EncounterDetailSerializer(serializers.ModelSerializer):
|
|
version = VersionSummarySerializer()
|
|
location_area = LocationAreaSummarySerializer()
|
|
pokemon = PokemonSummarySerializer()
|
|
condition_values = serializers.SerializerMethodField("get_encounter_conditions")
|
|
|
|
class Meta:
|
|
model = Encounter
|
|
fields = (
|
|
"min_level",
|
|
"max_level",
|
|
"version",
|
|
"encounter_slot",
|
|
"pokemon",
|
|
"location_area",
|
|
"condition_values",
|
|
)
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_encounter_conditions(self, obj):
|
|
condition_values = EncounterConditionValueMap.objects.filter(encounter=obj)
|
|
data = EncounterConditionValueMapSerializer(
|
|
condition_values, many=True, context=self.context
|
|
).data
|
|
values = []
|
|
|
|
for map in data:
|
|
values.append(map["condition_value"])
|
|
|
|
return values
|
|
|
|
|
|
class LocationAreaEncounterRateSerializer(serializers.ModelSerializer):
|
|
encounter_method = EncounterMethodSummarySerializer()
|
|
version = VersionSummarySerializer()
|
|
|
|
class Meta:
|
|
model = LocationAreaEncounterRate
|
|
fields = ("rate", "encounter_method", "version")
|
|
|
|
|
|
class LocationAreaNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = LocationAreaName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class LocationAreaDetailSerializer(serializers.ModelSerializer):
|
|
location = LocationSummarySerializer()
|
|
encounter_method_rates = serializers.SerializerMethodField("get_method_rates")
|
|
pokemon_encounters = serializers.SerializerMethodField("get_encounters")
|
|
names = LocationAreaNameSerializer(
|
|
many=True, read_only=True, source="locationareaname"
|
|
)
|
|
|
|
class Meta:
|
|
model = LocationArea
|
|
fields = (
|
|
"id",
|
|
"name",
|
|
"game_index",
|
|
"encounter_method_rates",
|
|
"location",
|
|
"names",
|
|
"pokemon_encounters",
|
|
)
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_method_rates(self, obj):
|
|
# Get encounters related to this area and pull out unique encounter methods
|
|
encounter_rates = LocationAreaEncounterRate.objects.filter(
|
|
location_area=obj
|
|
).order_by("encounter_method_id")
|
|
method_ids = encounter_rates.values("encounter_method_id").distinct()
|
|
encounter_rate_list = []
|
|
|
|
for id in method_ids:
|
|
encounter_rate_details = OrderedDict()
|
|
|
|
# Get each Unique Item by ID
|
|
encounter_method_object = EncounterMethod.objects.get(
|
|
pk=id["encounter_method_id"]
|
|
)
|
|
encounter_method_data = EncounterMethodSummarySerializer(
|
|
encounter_method_object, context=self.context
|
|
).data
|
|
encounter_rate_details["encounter_method"] = encounter_method_data
|
|
|
|
# Get Versions associated with each unique item
|
|
area_encounter_objects = encounter_rates.filter(
|
|
encounter_method_id=id["encounter_method_id"]
|
|
)
|
|
serializer = LocationAreaEncounterRateSerializer(
|
|
area_encounter_objects, many=True, context=self.context
|
|
)
|
|
encounter_rate_details["version_details"] = []
|
|
|
|
for area_encounter in serializer.data:
|
|
version_detail = OrderedDict()
|
|
|
|
version_detail["rate"] = area_encounter["rate"]
|
|
version_detail["version"] = area_encounter["version"]
|
|
|
|
encounter_rate_details["version_details"].append(version_detail)
|
|
|
|
encounter_rate_list.append(encounter_rate_details)
|
|
|
|
return encounter_rate_list
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_encounters(self, obj):
|
|
# get versions for later use
|
|
version_objects = Version.objects.all()
|
|
version_data = VersionSummarySerializer(
|
|
version_objects, many=True, context=self.context
|
|
).data
|
|
|
|
# all encounters associated with location area
|
|
all_encounters = Encounter.objects.filter(location_area=obj).order_by("pokemon")
|
|
encounters_list = []
|
|
|
|
# break encounters into pokemon groupings
|
|
for poke in all_encounters.values("pokemon").distinct():
|
|
pokemon_object = Pokemon.objects.get(pk=poke["pokemon"])
|
|
|
|
pokemon_detail = OrderedDict()
|
|
pokemon_detail["pokemon"] = PokemonSummarySerializer(
|
|
pokemon_object, context=self.context
|
|
).data
|
|
pokemon_detail["version_details"] = []
|
|
|
|
poke_encounters = all_encounters.filter(pokemon=poke["pokemon"]).order_by(
|
|
"version"
|
|
)
|
|
|
|
# each pokemon has multiple versions it could be encountered in
|
|
for ver in poke_encounters.values("version").distinct():
|
|
version_detail = OrderedDict()
|
|
version_detail["version"] = version_data[ver["version"] - 1]
|
|
version_detail["max_chance"] = 0
|
|
version_detail["encounter_details"] = []
|
|
|
|
poke_data = EncounterDetailSerializer(
|
|
poke_encounters.filter(version=ver["version"]),
|
|
many=True,
|
|
context=self.context,
|
|
).data
|
|
|
|
# each version has multiple ways a pokemon can be encountered
|
|
for encounter in poke_data:
|
|
slot = EncounterSlot.objects.get(pk=encounter["encounter_slot"])
|
|
slot_data = EncounterSlotSerializer(slot, context=self.context).data
|
|
del encounter["pokemon"]
|
|
del encounter["encounter_slot"]
|
|
del encounter["location_area"]
|
|
del encounter["version"]
|
|
encounter["chance"] = slot_data["chance"]
|
|
version_detail["max_chance"] += slot_data["chance"]
|
|
encounter["method"] = slot_data["encounter_method"]
|
|
|
|
version_detail["encounter_details"].append(encounter)
|
|
|
|
pokemon_detail["version_details"].append(version_detail)
|
|
|
|
encounters_list.append(pokemon_detail)
|
|
|
|
return encounters_list
|
|
|
|
|
|
class LocationGameIndexSerializer(serializers.ModelSerializer):
|
|
generation = GenerationSummarySerializer()
|
|
|
|
class Meta:
|
|
model = LocationGameIndex
|
|
fields = ("game_index", "generation")
|
|
|
|
|
|
class LocationNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = LocationName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class LocationDetailSerializer(serializers.ModelSerializer):
|
|
region = RegionSummarySerializer()
|
|
names = LocationNameSerializer(many=True, read_only=True, source="locationname")
|
|
game_indices = LocationGameIndexSerializer(
|
|
many=True, read_only=True, source="locationgameindex"
|
|
)
|
|
areas = LocationAreaSummarySerializer(
|
|
many=True, read_only=True, source="locationarea"
|
|
)
|
|
|
|
class Meta:
|
|
model = Location
|
|
fields = ("id", "name", "region", "names", "game_indices", "areas")
|
|
|
|
|
|
#########################
|
|
# ABILITY SERIALIZERS #
|
|
#########################
|
|
|
|
|
|
class AbilityEffectTextSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = AbilityEffectText
|
|
fields = ("effect", "short_effect", "language")
|
|
|
|
|
|
class AbilityFlavorTextSerializer(serializers.ModelSerializer):
|
|
flavor_text = serializers.CharField()
|
|
language = LanguageSummarySerializer()
|
|
version_group = VersionGroupSummarySerializer()
|
|
|
|
class Meta:
|
|
model = AbilityFlavorText
|
|
fields = ("flavor_text", "language", "version_group")
|
|
|
|
|
|
class AbilityChangeEffectTextSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = AbilityChangeEffectText
|
|
fields = (
|
|
"effect",
|
|
"language",
|
|
)
|
|
|
|
|
|
class AbilityChangeSerializer(serializers.ModelSerializer):
|
|
version_group = VersionGroupSummarySerializer()
|
|
effect_entries = AbilityChangeEffectTextSerializer(
|
|
many=True, read_only=True, source="abilitychangeeffecttext"
|
|
)
|
|
|
|
class Meta:
|
|
model = AbilityChange
|
|
fields = ("version_group", "effect_entries")
|
|
|
|
|
|
class AbilityNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = AbilityName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class AbilityDetailSerializer(serializers.ModelSerializer):
|
|
effect_entries = AbilityEffectTextSerializer(
|
|
many=True, read_only=True, source="abilityeffecttext"
|
|
)
|
|
flavor_text_entries = AbilityFlavorTextSerializer(
|
|
many=True, read_only=True, source="abilityflavortext"
|
|
)
|
|
names = AbilityNameSerializer(many=True, read_only=True, source="abilityname")
|
|
generation = GenerationSummarySerializer()
|
|
effect_changes = AbilityChangeSerializer(
|
|
many=True, read_only=True, source="abilitychange"
|
|
)
|
|
pokemon = serializers.SerializerMethodField("get_ability_pokemon")
|
|
|
|
class Meta:
|
|
model = Ability
|
|
fields = (
|
|
"id",
|
|
"name",
|
|
"is_main_series",
|
|
"generation",
|
|
"names",
|
|
"effect_entries",
|
|
"effect_changes",
|
|
"flavor_text_entries",
|
|
"pokemon",
|
|
)
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_ability_pokemon(self, obj):
|
|
pokemon_ability_objects = PokemonAbility.objects.filter(ability=obj)
|
|
data = PokemonAbilitySerializer(
|
|
pokemon_ability_objects, many=True, context=self.context
|
|
).data
|
|
pokemon = []
|
|
|
|
for poke in data:
|
|
del poke["ability"]
|
|
pokemon.append(poke)
|
|
|
|
return pokemon
|
|
|
|
|
|
######################
|
|
# STAT SERIALIZERS #
|
|
######################
|
|
|
|
|
|
class StatNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = StatName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class StatDetailSerializer(serializers.ModelSerializer):
|
|
names = StatNameSerializer(many=True, read_only=True, source="statname")
|
|
move_damage_class = MoveDamageClassSummarySerializer()
|
|
characteristics = CharacteristicSummarySerializer(
|
|
many=True, read_only=True, source="characteristic"
|
|
)
|
|
affecting_moves = serializers.SerializerMethodField("get_moves_that_affect")
|
|
affecting_natures = serializers.SerializerMethodField("get_natures_that_affect")
|
|
|
|
class Meta:
|
|
model = Stat
|
|
fields = (
|
|
"id",
|
|
"name",
|
|
"game_index",
|
|
"is_battle_only",
|
|
"affecting_moves",
|
|
"affecting_natures",
|
|
"characteristics",
|
|
"move_damage_class",
|
|
"names",
|
|
)
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_moves_that_affect(self, obj):
|
|
stat_change_objects = MoveMetaStatChange.objects.filter(stat=obj)
|
|
stat_changes = MoveMetaStatChangeSerializer(
|
|
stat_change_objects, many=True, context=self.context
|
|
).data
|
|
changes = OrderedDict([("increase", []), ("decrease", [])])
|
|
|
|
for change in stat_changes:
|
|
del change["stat"]
|
|
if change["change"] > 0:
|
|
changes["increase"].append(change)
|
|
else:
|
|
changes["decrease"].append(change)
|
|
|
|
return changes
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_natures_that_affect(self, obj):
|
|
increase_objects = Nature.objects.filter(increased_stat=obj)
|
|
increases = NatureSummarySerializer(
|
|
increase_objects, many=True, context=self.context
|
|
).data
|
|
decrease_objects = Nature.objects.filter(decreased_stat=obj)
|
|
decreases = NatureSummarySerializer(
|
|
decrease_objects, many=True, context=self.context
|
|
).data
|
|
|
|
return OrderedDict([("increase", increases), ("decrease", decreases)])
|
|
|
|
|
|
#############################
|
|
# ITEM POCKET SERIALIZERS #
|
|
#############################
|
|
|
|
|
|
class ItemPocketNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = ItemName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class ItemPocketDetailSerializer(serializers.ModelSerializer):
|
|
names = ItemPocketNameSerializer(many=True, read_only=True, source="itempocketname")
|
|
categories = ItemCategorySummarySerializer(
|
|
many=True, read_only=True, source="itemcategory"
|
|
)
|
|
|
|
class Meta:
|
|
model = ItemPocket
|
|
fields = ("id", "name", "categories", "categories", "names")
|
|
|
|
|
|
###############################
|
|
# ITEM CATEGORY SERIALIZERS #
|
|
###############################
|
|
class ItemCategoryNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = ItemName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class ItemCategoryDetailSerializer(serializers.ModelSerializer):
|
|
names = ItemCategoryNameSerializer(
|
|
many=True, read_only=True, source="itemcategoryname"
|
|
)
|
|
pocket = ItemPocketSummarySerializer(source="item_pocket")
|
|
items = ItemSummarySerializer(many=True, read_only=True, source="item")
|
|
|
|
class Meta:
|
|
model = ItemCategory
|
|
fields = ("id", "name", "items", "names", "pocket")
|
|
|
|
|
|
################################
|
|
# ITEM ATTRIBUTE SERIALIZERS #
|
|
################################
|
|
|
|
|
|
class ItemAttributeNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = ItemAttributeName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class ItemAttributeDescriptionSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = ItemAttributeDescription
|
|
fields = ("description", "language")
|
|
|
|
|
|
class ItemAttributeDetailSerializer(serializers.ModelSerializer):
|
|
names = ItemAttributeNameSerializer(
|
|
many=True, read_only=True, source="itemattributename"
|
|
)
|
|
descriptions = ItemAttributeDescriptionSerializer(
|
|
many=True, read_only=True, source="itemattributedescription"
|
|
)
|
|
items = serializers.SerializerMethodField("get_attribute_items")
|
|
|
|
class Meta:
|
|
model = ItemAttribute
|
|
fields = ("id", "name", "descriptions", "items", "names")
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_attribute_items(self, obj):
|
|
item_map_objects = ItemAttributeMap.objects.filter(item_attribute=obj)
|
|
items = []
|
|
|
|
for map in item_map_objects:
|
|
item_obj = Item.objects.get(pk=map.item.id)
|
|
item = ItemSummarySerializer(item_obj, context=self.context).data
|
|
items.append(item)
|
|
|
|
return items
|
|
|
|
|
|
###################################
|
|
# ITEM FLING EFFECT SERIALIZERS #
|
|
###################################
|
|
class ItemFlingEffectEffectTextSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = ItemFlingEffectEffectText
|
|
fields = ("effect", "language")
|
|
|
|
|
|
class ItemFlingEffectDetailSerializer(serializers.ModelSerializer):
|
|
effect_entries = ItemFlingEffectEffectTextSerializer(
|
|
many=True, read_only=True, source="itemflingeffecteffecttext"
|
|
)
|
|
items = ItemSummarySerializer(many=True, read_only=True, source="item")
|
|
|
|
class Meta:
|
|
model = ItemFlingEffect
|
|
fields = ("id", "name", "effect_entries", "items")
|
|
|
|
|
|
#######################
|
|
# ITEM SERIALIZERS #
|
|
#######################
|
|
class ItemFlavorTextSerializer(serializers.ModelSerializer):
|
|
text = serializers.CharField(source="flavor_text")
|
|
language = LanguageSummarySerializer()
|
|
version_group = VersionGroupSummarySerializer()
|
|
|
|
class Meta:
|
|
model = ItemFlavorText
|
|
fields = ("text", "version_group", "language")
|
|
|
|
|
|
class ItemEffectTextSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = ItemEffectText
|
|
fields = ("effect", "short_effect", "language")
|
|
|
|
|
|
class ItemGameIndexSerializer(serializers.ModelSerializer):
|
|
generation = GenerationSummarySerializer()
|
|
|
|
class Meta:
|
|
model = ItemGameIndex
|
|
fields = ("game_index", "generation")
|
|
|
|
|
|
class ItemNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = ItemName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class ItemSpritesSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = ItemSprites
|
|
fields = ("sprites",)
|
|
|
|
|
|
class ItemDetailSerializer(serializers.ModelSerializer):
|
|
names = ItemNameSerializer(many=True, read_only=True, source="itemname")
|
|
game_indices = ItemGameIndexSerializer(
|
|
many=True, read_only=True, source="itemgameindex"
|
|
)
|
|
effect_entries = ItemEffectTextSerializer(
|
|
many=True, read_only=True, source="itemeffecttext"
|
|
)
|
|
flavor_text_entries = ItemFlavorTextSerializer(
|
|
many=True, read_only=True, source="itemflavortext"
|
|
)
|
|
category = ItemCategorySummarySerializer(source="item_category")
|
|
attributes = serializers.SerializerMethodField("get_item_attributes")
|
|
fling_effect = ItemFlingEffectSummarySerializer(source="item_fling_effect")
|
|
held_by_pokemon = serializers.SerializerMethodField(source="get_held_by_pokemon")
|
|
baby_trigger_for = serializers.SerializerMethodField(source="get_baby_trigger_for")
|
|
sprites = serializers.SerializerMethodField("get_item_sprites")
|
|
machines = serializers.SerializerMethodField("get_item_machines")
|
|
|
|
class Meta:
|
|
model = Item
|
|
fields = (
|
|
"id",
|
|
"name",
|
|
"cost",
|
|
"fling_power",
|
|
"fling_effect",
|
|
"attributes",
|
|
"category",
|
|
"effect_entries",
|
|
"flavor_text_entries",
|
|
"game_indices",
|
|
"names",
|
|
"held_by_pokemon",
|
|
"sprites",
|
|
"baby_trigger_for",
|
|
"machines",
|
|
)
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_item_machines(self, obj):
|
|
machine_objects = Machine.objects.filter(item=obj)
|
|
|
|
machines = []
|
|
|
|
for machine_object in machine_objects:
|
|
machine_data = MachineSummarySerializer(
|
|
machine_object, context=self.context
|
|
).data
|
|
|
|
version_group_data = VersionGroupSummarySerializer(
|
|
machine_object.version_group, context=self.context
|
|
).data
|
|
|
|
machines.append(
|
|
{"machine": machine_data, "version_group": version_group_data}
|
|
)
|
|
|
|
return machines
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_item_sprites(self, obj):
|
|
sprites_object = ItemSprites.objects.get(item_id=obj)
|
|
return sprites_object.sprites
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_item_attributes(self, obj):
|
|
item_attribute_maps = ItemAttributeMap.objects.filter(item=obj)
|
|
serializer = ItemAttributeMapSerializer(
|
|
item_attribute_maps, many=True, context=self.context
|
|
)
|
|
data = serializer.data
|
|
|
|
attributes = []
|
|
|
|
for map in data:
|
|
attribute = OrderedDict()
|
|
attribute["name"] = map["attribute"]["name"]
|
|
attribute["url"] = map["attribute"]["url"]
|
|
attributes.append(attribute)
|
|
|
|
return attributes
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_held_by_pokemon(self, obj):
|
|
pokemon_items = PokemonItem.objects.filter(item=obj).order_by("pokemon_id")
|
|
pokemon_ids = pokemon_items.values("pokemon_id").distinct()
|
|
pokemon_list = []
|
|
|
|
for id in pokemon_ids:
|
|
item_pokemon_details = OrderedDict()
|
|
|
|
# Get each Unique Item by ID
|
|
pokemon_object = Pokemon.objects.get(pk=id["pokemon_id"])
|
|
pokemon_data = PokemonSummarySerializer(
|
|
pokemon_object, context=self.context
|
|
).data
|
|
item_pokemon_details["pokemon"] = pokemon_data
|
|
|
|
# Get Versions associated with each unique item
|
|
pokemon_item_objects = pokemon_items.filter(pokemon_id=id["pokemon_id"])
|
|
serializer = PokemonItemSerializer(
|
|
pokemon_item_objects, many=True, context=self.context
|
|
)
|
|
item_pokemon_details["version_details"] = []
|
|
|
|
for pokemon in serializer.data:
|
|
version_detail = OrderedDict()
|
|
version_detail["rarity"] = pokemon["rarity"]
|
|
version_detail["version"] = pokemon["version"]
|
|
item_pokemon_details["version_details"].append(version_detail)
|
|
|
|
pokemon_list.append(item_pokemon_details)
|
|
|
|
return pokemon_list
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_baby_trigger_for(self, obj):
|
|
try:
|
|
chain_object = EvolutionChain.objects.get(baby_trigger_item=obj)
|
|
data = EvolutionChainSummarySerializer(
|
|
chain_object, context=self.context
|
|
).data
|
|
except EvolutionChain.DoesNotExist:
|
|
data = None
|
|
|
|
return data
|
|
|
|
|
|
########################
|
|
# NATURE SERIALIZERS #
|
|
########################
|
|
|
|
|
|
class NatureBattleStylePreferenceSerializer(serializers.ModelSerializer):
|
|
move_battle_style = MoveBattleStyleSummarySerializer()
|
|
|
|
class Meta:
|
|
model = NatureBattleStylePreference
|
|
fields = (
|
|
"low_hp_preference",
|
|
"high_hp_preference",
|
|
"move_battle_style",
|
|
)
|
|
|
|
|
|
class NatureNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = NatureName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class NatureDetailSerializer(serializers.ModelSerializer):
|
|
names = NatureNameSerializer(many=True, read_only=True, source="naturename")
|
|
decreased_stat = StatSummarySerializer()
|
|
increased_stat = StatSummarySerializer()
|
|
likes_flavor = BerryFlavorSummarySerializer()
|
|
hates_flavor = BerryFlavorSummarySerializer()
|
|
berries = BerrySummarySerializer(many=True, read_only=True, source="berry")
|
|
pokeathlon_stat_changes = serializers.SerializerMethodField("get_pokeathlon_stats")
|
|
move_battle_style_preferences = NatureBattleStylePreferenceSerializer(
|
|
many=True, read_only=True, source="naturebattlestylepreference"
|
|
)
|
|
|
|
class Meta:
|
|
model = Nature
|
|
fields = (
|
|
"id",
|
|
"name",
|
|
"decreased_stat",
|
|
"increased_stat",
|
|
"likes_flavor",
|
|
"hates_flavor",
|
|
"berries",
|
|
"pokeathlon_stat_changes",
|
|
"move_battle_style_preferences",
|
|
"names",
|
|
)
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_pokeathlon_stats(self, obj):
|
|
pokeathlon_stat_objects = NaturePokeathlonStat.objects.filter(nature=obj)
|
|
pokeathlon_stats = NaturePokeathlonStatSerializer(
|
|
pokeathlon_stat_objects, many=True, context=self.context
|
|
).data
|
|
|
|
for stat in pokeathlon_stats:
|
|
del stat["nature"]
|
|
|
|
return pokeathlon_stats
|
|
|
|
|
|
#######################
|
|
# BERRY SERIALIZERS #
|
|
#######################
|
|
|
|
|
|
class BerryFirmnessNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = BerryFirmnessName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class BerryFirmnessDetailSerializer(serializers.ModelSerializer):
|
|
names = BerryFirmnessNameSerializer(
|
|
many=True, read_only=True, source="berryfirmnessname"
|
|
)
|
|
berries = BerrySummarySerializer(many=True, read_only=True, source="berry")
|
|
|
|
class Meta:
|
|
model = BerryFirmness
|
|
fields = ("id", "name", "berries", "names")
|
|
|
|
|
|
class BerryFlavorNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = BerryFlavorName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class BerryFlavorDetailSerializer(serializers.ModelSerializer):
|
|
names = BerryFlavorNameSerializer(
|
|
many=True, read_only=True, source="berryflavorname"
|
|
)
|
|
contest_type = ContestTypeSummarySerializer()
|
|
berries = serializers.SerializerMethodField("get_berries_with_flavor")
|
|
|
|
class Meta:
|
|
model = BerryFlavor
|
|
fields = ("id", "name", "berries", "contest_type", "names")
|
|
|
|
@extend_schema_field(field={'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'potency', 'berry' ],
|
|
'properties': {
|
|
'potency': {
|
|
'type': 'integer',
|
|
'example': 10
|
|
},
|
|
'berry': {
|
|
'type': 'object',
|
|
'require': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'description': 'The name of the berry',
|
|
'example': 'rowap'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'description': 'The URL to get more information about the berry',
|
|
'example': 'https://pokeapi.co/api/v2/berry/64/'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
})
|
|
def get_berries_with_flavor(self, obj):
|
|
flavor_map_objects = BerryFlavorMap.objects.filter(
|
|
berry_flavor=obj, potency__gt=0
|
|
).order_by("potency")
|
|
flavor_maps = BerryFlavorMapSerializer(
|
|
flavor_map_objects, many=True, context=self.context
|
|
).data
|
|
|
|
for map in flavor_maps:
|
|
del map["flavor"]
|
|
|
|
return flavor_maps
|
|
|
|
|
|
class BerryDetailSerializer(serializers.ModelSerializer):
|
|
item = ItemSummarySerializer()
|
|
natural_gift_type = TypeSummarySerializer()
|
|
firmness = BerryFirmnessSummarySerializer(source="berry_firmness")
|
|
flavors = serializers.SerializerMethodField("get_berry_flavors")
|
|
|
|
class Meta:
|
|
model = Berry
|
|
fields = (
|
|
"id",
|
|
"name",
|
|
"growth_time",
|
|
"max_harvest",
|
|
"natural_gift_power",
|
|
"size",
|
|
"smoothness",
|
|
"soil_dryness",
|
|
"firmness",
|
|
"flavors",
|
|
"item",
|
|
"natural_gift_type",
|
|
)
|
|
|
|
@extend_schema_field(field={'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'potency', 'flavor' ],
|
|
'properties': {
|
|
'potency': {
|
|
'type': 'integer',
|
|
'example': 10
|
|
},
|
|
'flavor': {
|
|
'type': 'object',
|
|
'require': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'description': 'The name of the flavor',
|
|
'example': 'spicy'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'description': 'The URL to get more information about the flavor',
|
|
'example': 'https://pokeapi.co/api/v2/berry-flavor/1/'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
})
|
|
def get_berry_flavors(self, obj):
|
|
flavor_map_objects = BerryFlavorMap.objects.filter(berry=obj)
|
|
flavor_maps = BerryFlavorMapSerializer(
|
|
flavor_map_objects, many=True, context=self.context
|
|
).data
|
|
flavors = []
|
|
|
|
for map in flavor_maps:
|
|
del map["berry"]
|
|
flavors.append(map)
|
|
|
|
return flavors
|
|
|
|
|
|
###########################
|
|
# EGG GROUP SERIALIZERS #
|
|
###########################
|
|
class PokemonEggGroupSerializer(serializers.ModelSerializer):
|
|
species = PokemonSpeciesSummarySerializer(source="pokemon_species")
|
|
egg_group = EggGroupSummarySerializer()
|
|
|
|
class Meta:
|
|
model = PokemonEggGroup
|
|
fields = ("species", "egg_group")
|
|
|
|
|
|
class EggGroupNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = EggGroupName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class EggGroupDetailSerializer(serializers.ModelSerializer):
|
|
names = EggGroupNameSerializer(many=True, read_only=True, source="egggroupname")
|
|
pokemon_species = serializers.SerializerMethodField("get_species")
|
|
|
|
class Meta:
|
|
model = EggGroup
|
|
fields = ("id", "name", "names", "pokemon_species")
|
|
|
|
@extend_schema_field(field={'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'potency', 'flavor' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'description': 'Pokemon species name.',
|
|
'example': 'bulbasaur'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'description': 'The URL to get more information about the species',
|
|
'example': 'https://pokeapi.co/api/v2/pokemon-species/1/'
|
|
},
|
|
}
|
|
},
|
|
})
|
|
def get_species(self, obj):
|
|
results = PokemonEggGroup.objects.filter(egg_group=obj)
|
|
data = PokemonEggGroupSerializer(results, many=True, context=self.context).data
|
|
associated_species = []
|
|
for species in data:
|
|
associated_species.append(species["species"])
|
|
|
|
return associated_species
|
|
|
|
|
|
######################
|
|
# TYPE SERIALIZERS #
|
|
######################
|
|
# https://stackoverflow.com/a/45987450/3482533
|
|
class TypeEfficacySerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = TypeEfficacy
|
|
fields = "__all__"
|
|
|
|
|
|
class TypeEfficacyPastSerializer(serializers.ModelSerializer):
|
|
generation = GenerationSummarySerializer()
|
|
|
|
class Meta:
|
|
model = TypeEfficacyPast
|
|
fields = ("target_type", "damage_type", "damage_factor", "generation")
|
|
|
|
|
|
class TypeGameIndexSerializer(serializers.ModelSerializer):
|
|
generation = GenerationSummarySerializer()
|
|
|
|
class Meta:
|
|
model = TypeGameIndex
|
|
fields = ("game_index", "generation")
|
|
|
|
|
|
class TypeNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = TypeName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class TypeDetailSerializer(serializers.ModelSerializer):
|
|
"""
|
|
Serializer for the Type resource
|
|
"""
|
|
|
|
generation = GenerationSummarySerializer()
|
|
names = AbilityNameSerializer(many=True, read_only=True, source="typename")
|
|
game_indices = TypeGameIndexSerializer(
|
|
many=True, read_only=True, source="typegameindex"
|
|
)
|
|
move_damage_class = MoveDamageClassSummarySerializer()
|
|
damage_relations = serializers.SerializerMethodField("get_type_relationships")
|
|
past_damage_relations = serializers.SerializerMethodField(
|
|
"get_type_past_relationships"
|
|
)
|
|
pokemon = serializers.SerializerMethodField("get_type_pokemon")
|
|
moves = MoveSummarySerializer(many=True, read_only=True, source="move")
|
|
|
|
class Meta:
|
|
model = Type
|
|
fields = (
|
|
"id",
|
|
"name",
|
|
"damage_relations",
|
|
"past_damage_relations",
|
|
"game_indices",
|
|
"generation",
|
|
"move_damage_class",
|
|
"names",
|
|
"pokemon",
|
|
"moves",
|
|
)
|
|
|
|
# adds an entry for the given type with the given damage
|
|
# factor in the given direction to the set of relations
|
|
|
|
def add_type_entry(self, relations, type, damage_factor, direction="_damage_to"):
|
|
if damage_factor == 200:
|
|
relations["double" + direction].append(
|
|
TypeSummarySerializer(type, context=self.context).data
|
|
)
|
|
elif damage_factor == 50:
|
|
relations["half" + direction].append(
|
|
TypeSummarySerializer(type, context=self.context).data
|
|
)
|
|
elif damage_factor == 0:
|
|
relations["no" + direction].append(
|
|
TypeSummarySerializer(type, context=self.context).data
|
|
)
|
|
|
|
@extend_schema_field(field={'type': 'object',
|
|
'required': [
|
|
'no_damage_to',
|
|
'half_damage_to',
|
|
'double_damage_to',
|
|
'no_damage_from',
|
|
'half_damage_from',
|
|
'double_damage_from'
|
|
],
|
|
'properties': {
|
|
'no_damage_to': {
|
|
'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'flying'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/type/3/'
|
|
}
|
|
}
|
|
}
|
|
},
|
|
'half_damage_to': {
|
|
'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'bug'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/type/7/'
|
|
}
|
|
}
|
|
}
|
|
},
|
|
'double_damage_to': {
|
|
'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'poison'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/type/4/'
|
|
}
|
|
}
|
|
}
|
|
},
|
|
'no_damage_from': {
|
|
'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'electric'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/type/13/'
|
|
}
|
|
}
|
|
}
|
|
},
|
|
'half_damage_from': {
|
|
'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'poison'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/type/4/'
|
|
}
|
|
}
|
|
}
|
|
},
|
|
'double_damage_from': {
|
|
'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'water'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/type/11/'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
})
|
|
def get_type_relationships(self, obj):
|
|
relations = OrderedDict()
|
|
relations["no_damage_to"] = []
|
|
relations["half_damage_to"] = []
|
|
relations["double_damage_to"] = []
|
|
|
|
relations["no_damage_from"] = []
|
|
relations["half_damage_from"] = []
|
|
relations["double_damage_from"] = []
|
|
|
|
# Damage To
|
|
results = TypeEfficacy.objects.filter(damage_type=obj)
|
|
serializer = TypeEfficacySerializer(results, many=True, context=self.context)
|
|
|
|
for relation in serializer.data:
|
|
type = Type.objects.get(pk=relation["target_type"])
|
|
damage_factor = relation["damage_factor"]
|
|
self.add_type_entry(relations, type, damage_factor, direction="_damage_to")
|
|
|
|
# Damage From
|
|
results = TypeEfficacy.objects.filter(target_type=obj)
|
|
serializer = TypeEfficacySerializer(results, many=True, context=self.context)
|
|
|
|
for relation in serializer.data:
|
|
type = Type.objects.get(pk=relation["damage_type"])
|
|
damage_factor = relation["damage_factor"]
|
|
self.add_type_entry(
|
|
relations, type, damage_factor, direction="_damage_from"
|
|
)
|
|
|
|
return relations
|
|
|
|
# takes a list of past type relations by generation and
|
|
# returns a list of lists where each list has the entries
|
|
# for a single generation
|
|
def group_relations_by_generation(self, serializer_data):
|
|
data_by_gen = []
|
|
|
|
current_generation = ""
|
|
generation_data = []
|
|
for relation in serializer_data:
|
|
gen_name = relation["generation"]["name"]
|
|
if gen_name != current_generation:
|
|
# first item for this generation so create its list
|
|
current_generation = gen_name
|
|
generation_data = [relation]
|
|
data_by_gen.append(generation_data)
|
|
else:
|
|
# add to this generation's list
|
|
generation_data.append(relation)
|
|
|
|
return data_by_gen
|
|
|
|
# removes the entry for the given type in
|
|
# the given direction from the set of relations
|
|
def remove_type_entry(self, relations, type, direction="_damage_to"):
|
|
for k in ["double", "half", "no"]:
|
|
rel_list = relations[k + direction]
|
|
for i, o in enumerate(rel_list):
|
|
if o["name"] == type.name:
|
|
del rel_list[i]
|
|
return
|
|
|
|
# returns past type relationships for the given type object
|
|
@extend_schema_field(field={'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'generation', 'damage_relations' ],
|
|
'properties': {
|
|
'generation': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'generation-v'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/generation/5/'
|
|
}
|
|
}
|
|
},
|
|
'damage_relations': {
|
|
'type': 'object',
|
|
'required': [
|
|
'no_damage_to',
|
|
'half_damage_to',
|
|
'double_damage_to',
|
|
'no_damage_from',
|
|
'half_damage_from',
|
|
'double_damage_from'
|
|
],
|
|
'properties': {
|
|
'no_damage_to': {
|
|
'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'flying'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/type/3/'
|
|
}
|
|
}
|
|
}
|
|
},
|
|
'half_damage_to': {
|
|
'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'bug'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/type/7/'
|
|
}
|
|
}
|
|
}
|
|
},
|
|
'double_damage_to': {
|
|
'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'poison'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/type/4/'
|
|
}
|
|
}
|
|
}
|
|
},
|
|
'no_damage_from': {
|
|
'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'electric'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/type/13/'
|
|
}
|
|
}
|
|
}
|
|
},
|
|
'half_damage_from': {
|
|
'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'poison'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/type/4/'
|
|
}
|
|
}
|
|
}
|
|
},
|
|
'double_damage_from': {
|
|
'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'water'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/type/11/'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
})
|
|
def get_type_past_relationships(self, obj):
|
|
# collect data from DB
|
|
damage_type_results = list(TypeEfficacyPast.objects.filter(damage_type=obj))
|
|
target_type_results = list(TypeEfficacyPast.objects.filter(target_type=obj))
|
|
serializer = TypeEfficacyPastSerializer(
|
|
damage_type_results + target_type_results, many=True, context=self.context
|
|
)
|
|
|
|
# group data by generation
|
|
data_by_gen = self.group_relations_by_generation(serializer.data)
|
|
|
|
# process each generation's data in turn
|
|
final_data = []
|
|
past_relations = {}
|
|
for gen_data in data_by_gen:
|
|
# create past relations object for this generation
|
|
past_relations = OrderedDict()
|
|
|
|
# set generation
|
|
past_relations["generation"] = gen_data[0]["generation"]
|
|
|
|
# use current damage relations object
|
|
past_relations["damage_relations"] = self.get_type_relationships(obj)
|
|
relations = past_relations["damage_relations"]
|
|
|
|
current_gen = Generation.objects.get(name=gen_data[0]["generation"]["name"])
|
|
|
|
# remove types not yet introduced
|
|
# e.g. Poison has no effect on Steel, but Steel was not present in generation I
|
|
# so it should be absent from the list
|
|
relations["no_damage_to"] = self.remove_newer_types(
|
|
relations["no_damage_to"], current_gen
|
|
)
|
|
relations["half_damage_to"] = self.remove_newer_types(
|
|
relations["half_damage_to"], current_gen
|
|
)
|
|
relations["double_damage_to"] = self.remove_newer_types(
|
|
relations["double_damage_to"], current_gen
|
|
)
|
|
relations["no_damage_from"] = self.remove_newer_types(
|
|
relations["no_damage_from"], current_gen
|
|
)
|
|
relations["half_damage_from"] = self.remove_newer_types(
|
|
relations["half_damage_from"], current_gen
|
|
)
|
|
relations["double_damage_from"] = self.remove_newer_types(
|
|
relations["double_damage_from"], current_gen
|
|
)
|
|
|
|
# populate offensive relations
|
|
results = list(filter(lambda x: x["damage_type"] == obj.id, gen_data))
|
|
for relation in results:
|
|
type = Type.objects.get(pk=relation["target_type"])
|
|
|
|
# remove conflicting entry if it exists
|
|
self.remove_type_entry(relations, type, direction="_damage_to")
|
|
|
|
# add entry
|
|
damage_factor = relation["damage_factor"]
|
|
self.add_type_entry(
|
|
relations, type, damage_factor, direction="_damage_to"
|
|
)
|
|
|
|
del relation["generation"]
|
|
|
|
# populate defensive relations
|
|
results = list(filter(lambda x: x["target_type"] == obj.id, gen_data))
|
|
for relation in results:
|
|
type = Type.objects.get(pk=relation["damage_type"])
|
|
|
|
# remove conflicting entry if it exists
|
|
self.remove_type_entry(relations, type, direction="_damage_from")
|
|
|
|
# add entry
|
|
damage_factor = relation["damage_factor"]
|
|
self.add_type_entry(
|
|
relations, type, damage_factor, direction="_damage_from"
|
|
)
|
|
|
|
del relation["generation"]
|
|
|
|
# add to final list
|
|
final_data.append(past_relations)
|
|
|
|
return final_data
|
|
|
|
def remove_newer_types(self, relations, current_gen):
|
|
return list(filter(lambda x: self.type_is_present(x, current_gen), relations))
|
|
|
|
def type_is_present(self, type, current_gen):
|
|
type_obj = Type.objects.get(name=type["name"])
|
|
gen_introduced = Generation.objects.get(pk=type_obj.generation.id)
|
|
return gen_introduced.id <= current_gen.id
|
|
|
|
@extend_schema_field(field={'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'potency', 'flavor' ],
|
|
'properties': {
|
|
'slot': {
|
|
'type': 'integer',
|
|
'example': 1
|
|
},
|
|
'pokemon': {
|
|
'type': 'object',
|
|
'require': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'description': 'The name of the pokemon',
|
|
'example': 'sandshrew'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'description': 'The URL to get more information about the pokemon',
|
|
'example': 'https://pokeapi.co/api/v2/pokemon/27/'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
})
|
|
def get_type_pokemon(self, obj):
|
|
poke_type_objects = PokemonType.objects.filter(type=obj)
|
|
poke_types = PokemonTypeSerializer(
|
|
poke_type_objects, many=True, context=self.context
|
|
).data
|
|
|
|
for poke_type in poke_types:
|
|
del poke_type["type"]
|
|
|
|
return poke_types
|
|
|
|
|
|
#########################
|
|
# MACHINE SERIALIZERS #
|
|
#########################
|
|
class MachineDetailSerializer(serializers.ModelSerializer):
|
|
item = ItemSummarySerializer()
|
|
version_group = VersionGroupSummarySerializer()
|
|
move = MoveSummarySerializer()
|
|
|
|
class Meta:
|
|
model = Machine
|
|
fields = ("id", "item", "version_group", "move")
|
|
|
|
|
|
###################################
|
|
# MOVE BATTLE STYLE SERIALIZERS #
|
|
###################################
|
|
class MoveBattleStyleNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = MoveBattleStyleName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class MoveBattleStyleDetailSerializer(serializers.ModelSerializer):
|
|
names = MoveBattleStyleNameSerializer(
|
|
many=True, read_only=True, source="movebattlestylename"
|
|
)
|
|
|
|
class Meta:
|
|
model = MoveBattleStyle
|
|
fields = ("id", "name", "names")
|
|
|
|
|
|
###################################
|
|
# MOVE DAMAGE CLASS SERIALIZERS #
|
|
###################################
|
|
class MoveDamageClassNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = MoveDamageClassName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class MoveDamageClassDescriptionSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = MoveDamageClassDescription
|
|
fields = ("description", "language")
|
|
|
|
|
|
class MoveDamageClassDetailSerializer(serializers.ModelSerializer):
|
|
names = MoveDamageClassNameSerializer(
|
|
many=True, read_only=True, source="movedamageclassname"
|
|
)
|
|
descriptions = MoveDamageClassDescriptionSerializer(
|
|
many=True, read_only=True, source="movedamageclassdescription"
|
|
)
|
|
moves = MoveSummarySerializer(many=True, read_only=True, source="move")
|
|
|
|
class Meta:
|
|
model = MoveDamageClass
|
|
fields = (
|
|
"id",
|
|
"name",
|
|
"descriptions",
|
|
"moves",
|
|
"names",
|
|
)
|
|
|
|
|
|
###########################
|
|
# MOVE META SERIALIZERS #
|
|
###########################
|
|
class MoveMetaAilmentNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = MoveMetaAilmentName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class MoveMetaAilmentDetailSerializer(serializers.ModelSerializer):
|
|
names = MoveMetaAilmentNameSerializer(
|
|
many=True, read_only=True, source="movemetaailmentname"
|
|
)
|
|
moves = serializers.SerializerMethodField("get_ailment_moves")
|
|
|
|
class Meta:
|
|
model = MoveMetaAilment
|
|
fields = ("id", "name", "moves", "names")
|
|
|
|
@extend_schema_field(field={'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'thunder-punch'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/move/9/'
|
|
}
|
|
}
|
|
},
|
|
})
|
|
def get_ailment_moves(self, obj):
|
|
move_meta_objects = MoveMeta.objects.filter(move_meta_ailment=obj)
|
|
moves = []
|
|
|
|
for meta in move_meta_objects:
|
|
move_obj = Move.objects.get(pk=meta.move.id)
|
|
data = MoveSummarySerializer(move_obj, context=self.context).data
|
|
moves.append(data)
|
|
|
|
return moves
|
|
|
|
|
|
class MoveMetaCategoryDescriptionSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = MoveMetaCategoryDescription
|
|
fields = ("description", "language")
|
|
|
|
|
|
class MoveMetaCategoryDetailSerializer(serializers.ModelSerializer):
|
|
descriptions = MoveMetaCategoryDescriptionSerializer(
|
|
many=True, read_only=True, source="movemetacategorydescription"
|
|
)
|
|
moves = serializers.SerializerMethodField("get_category_moves")
|
|
|
|
class Meta:
|
|
model = MoveMetaCategory
|
|
fields = ("id", "name", "descriptions", "moves")
|
|
|
|
@extend_schema_field(field={'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'sing'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/move/47/'
|
|
}
|
|
}
|
|
},
|
|
})
|
|
def get_category_moves(self, obj):
|
|
move_meta_objects = MoveMeta.objects.filter(move_meta_category=obj)
|
|
moves = []
|
|
|
|
for meta in move_meta_objects:
|
|
move_obj = Move.objects.get(pk=meta.move.id)
|
|
data = MoveSummarySerializer(move_obj, context=self.context).data
|
|
moves.append(data)
|
|
|
|
return moves
|
|
|
|
|
|
class MoveMetaSerializer(serializers.ModelSerializer):
|
|
ailment = MoveMetaAilmentSummarySerializer(source="move_meta_ailment")
|
|
category = MoveMetaCategorySummarySerializer(source="move_meta_category")
|
|
|
|
class Meta:
|
|
model = MoveMeta
|
|
fields = (
|
|
"ailment",
|
|
"category",
|
|
"min_hits",
|
|
"max_hits",
|
|
"min_turns",
|
|
"max_turns",
|
|
"drain",
|
|
"healing",
|
|
"crit_rate",
|
|
"ailment_chance",
|
|
"flinch_chance",
|
|
"stat_chance",
|
|
)
|
|
|
|
|
|
#############################
|
|
# MOVE TARGET SERIALIZERS #
|
|
#############################
|
|
class MoveTargetNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = MoveTargetName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class MoveTargetDescriptionSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = MoveTargetDescription
|
|
fields = ("description", "language")
|
|
|
|
|
|
class MoveTargetDetailSerializer(serializers.ModelSerializer):
|
|
names = MoveTargetNameSerializer(many=True, read_only=True, source="movetargetname")
|
|
descriptions = MoveTargetDescriptionSerializer(
|
|
many=True, read_only=True, source="movetargetdescription"
|
|
)
|
|
moves = MoveSummarySerializer(many=True, read_only=True, source="move")
|
|
|
|
class Meta:
|
|
model = MoveTarget
|
|
fields = ("id", "name", "descriptions", "moves", "names")
|
|
|
|
|
|
######################
|
|
# MOVE SERIALIZERS #
|
|
######################
|
|
class MoveNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = AbilityName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class MoveChangeSerializer(serializers.ModelSerializer):
|
|
version_group = VersionGroupSummarySerializer()
|
|
type = TypeSummarySerializer()
|
|
effect_entries = serializers.SerializerMethodField("get_effects")
|
|
effect_chance = serializers.IntegerField(source="move_effect_chance")
|
|
|
|
class Meta:
|
|
model = MoveChange
|
|
fields = (
|
|
"accuracy",
|
|
"power",
|
|
"pp",
|
|
"effect_chance",
|
|
"effect_entries",
|
|
"type",
|
|
"version_group",
|
|
)
|
|
|
|
@extend_schema_field(field={'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'effect', 'short_effect', 'language' ],
|
|
'properties': {
|
|
'effect': {
|
|
'type': 'string',
|
|
'example': 'Inflicts [regular damage]{mechanic:regular-damage}.'
|
|
},
|
|
'short_effect': {
|
|
'type': 'string',
|
|
'example': 'Inflicts regular damage with no additional effect.'
|
|
},
|
|
'language': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'en'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/language/9/'
|
|
}
|
|
}
|
|
}
|
|
},
|
|
},
|
|
})
|
|
def get_effects(self, obj):
|
|
effect_texts = MoveEffectEffectText.objects.filter(move_effect=obj.move_effect)
|
|
data = MoveEffectEffectTextSerializer(
|
|
effect_texts, many=True, context=self.context
|
|
).data
|
|
|
|
return data
|
|
|
|
|
|
class MoveEffectEffectTextSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = MoveEffectEffectText
|
|
fields = ("effect", "short_effect", "language")
|
|
|
|
|
|
class MoveEffectChangeEffectTextSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = MoveEffectChangeEffectText
|
|
fields = ("effect", "language")
|
|
|
|
|
|
class MoveEffectChangeSerializer(serializers.ModelSerializer):
|
|
version_group = VersionGroupSummarySerializer()
|
|
effect_entries = MoveEffectChangeEffectTextSerializer(
|
|
many=True, read_only=True, source="moveeffectchangeeffecttext"
|
|
)
|
|
|
|
class Meta:
|
|
model = MoveEffectChange
|
|
fields = ("version_group", "effect_entries")
|
|
|
|
|
|
class MoveFlavorTextSerializer(serializers.ModelSerializer):
|
|
flavor_text = serializers.CharField()
|
|
language = LanguageSummarySerializer()
|
|
version_group = VersionGroupSummarySerializer()
|
|
|
|
class Meta:
|
|
model = MoveFlavorText
|
|
fields = ("flavor_text", "language", "version_group")
|
|
|
|
|
|
class MoveDetailSerializer(serializers.ModelSerializer):
|
|
generation = GenerationSummarySerializer()
|
|
type = TypeSummarySerializer()
|
|
target = MoveTargetSummarySerializer(source="move_target")
|
|
contest_type = ContestTypeSummarySerializer()
|
|
contest_effect = ContestEffectSummarySerializer()
|
|
damage_class = MoveDamageClassSummarySerializer(source="move_damage_class")
|
|
meta = MoveMetaSerializer(read_only=True, source="movemeta")
|
|
names = MoveNameSerializer(many=True, read_only=True, source="movename")
|
|
effect_entries = serializers.SerializerMethodField("get_effect_text")
|
|
effect_chance = serializers.IntegerField(source="move_effect_chance")
|
|
contest_combos = serializers.SerializerMethodField("get_combos")
|
|
stat_changes = serializers.SerializerMethodField("get_move_stat_change")
|
|
super_contest_effect = SuperContestEffectSummarySerializer()
|
|
past_values = MoveChangeSerializer(many=True, read_only=True, source="movechange")
|
|
effect_changes = serializers.SerializerMethodField("get_effect_change_text")
|
|
machines = serializers.SerializerMethodField("get_move_machines")
|
|
flavor_text_entries = MoveFlavorTextSerializer(
|
|
many=True, read_only=True, source="moveflavortext"
|
|
)
|
|
learned_by_pokemon = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = Move
|
|
fields = (
|
|
"id",
|
|
"name",
|
|
"accuracy",
|
|
"effect_chance",
|
|
"pp",
|
|
"priority",
|
|
"power",
|
|
"contest_combos",
|
|
"contest_type",
|
|
"contest_effect",
|
|
"damage_class",
|
|
"effect_entries",
|
|
"effect_changes",
|
|
"generation",
|
|
"meta",
|
|
"names",
|
|
"past_values",
|
|
"stat_changes",
|
|
"super_contest_effect",
|
|
"target",
|
|
"type",
|
|
"machines",
|
|
"flavor_text_entries",
|
|
"learned_by_pokemon",
|
|
)
|
|
|
|
@extend_schema_field(field={'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'clefairy'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/pokemon/35/'
|
|
}
|
|
}
|
|
},
|
|
})
|
|
def get_learned_by_pokemon(self, obj):
|
|
pokemon_moves = PokemonMove.objects.filter(move_id=obj).order_by("pokemon_id")
|
|
|
|
pokemon_list = []
|
|
|
|
pokemon_ids = pokemon_moves.values("pokemon_id").distinct()
|
|
|
|
for id in pokemon_ids:
|
|
pokemon_object = Pokemon.objects.get(pk=id["pokemon_id"])
|
|
pokemon_data = PokemonSummarySerializer(
|
|
pokemon_object, context=self.context
|
|
).data
|
|
|
|
pokemon_list.append(pokemon_data)
|
|
|
|
return pokemon_list
|
|
|
|
@extend_schema_field(field={'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'machine', 'version_group' ],
|
|
'properties': {
|
|
'machine': {
|
|
'type': 'object',
|
|
'required': [ 'url' ],
|
|
'properties': {
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/machine/1/'
|
|
}
|
|
}
|
|
},
|
|
'version_group': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'sword-shield'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/version-group/1/'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
})
|
|
def get_move_machines(self, obj):
|
|
machine_objects = Machine.objects.filter(move=obj)
|
|
|
|
machines = []
|
|
|
|
for machine_object in machine_objects:
|
|
machine_data = MachineSummarySerializer(
|
|
machine_object, context=self.context
|
|
).data
|
|
|
|
version_group_data = VersionGroupSummarySerializer(
|
|
machine_object.version_group, context=self.context
|
|
).data
|
|
|
|
machines.append(
|
|
{"machine": machine_data, "version_group": version_group_data}
|
|
)
|
|
|
|
return machines
|
|
|
|
@extend_schema_field(field={'type': 'object',
|
|
'properties': {
|
|
'required': [ 'normal', 'super' ],
|
|
'normal': {
|
|
'type': 'object',
|
|
'required': [ 'use_before', 'use_after' ],
|
|
'properties': {
|
|
'use_before': {
|
|
'type': 'array',
|
|
'nullable': True,
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'fire-punch'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/move/7/'
|
|
}
|
|
}
|
|
}
|
|
},
|
|
'use_after': {
|
|
'type': 'array',
|
|
'nullable': True,
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'ice-punch'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/move/8/'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
'super': {
|
|
'type': 'object',
|
|
'required': [ 'use_before', 'use_after' ],
|
|
'properties': {
|
|
'use_before': {
|
|
'type': 'array',
|
|
'nullable': True,
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'night-slash'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/move/400/'
|
|
}
|
|
}
|
|
}
|
|
},
|
|
'use_after': {
|
|
'type': 'array',
|
|
'nullable': True,
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'focus-energy'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/move/116/'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
},
|
|
})
|
|
def get_combos(self, obj):
|
|
normal_before_objects = ContestCombo.objects.filter(first_move=obj)
|
|
normal_before_data = ContestComboSerializer(
|
|
normal_before_objects, many=True, context=self.context
|
|
).data
|
|
normal_after_objects = ContestCombo.objects.filter(second_move=obj)
|
|
normal_after_data = ContestComboSerializer(
|
|
normal_after_objects, many=True, context=self.context
|
|
).data
|
|
|
|
super_before_objects = SuperContestCombo.objects.filter(first_move=obj)
|
|
super_before_data = SuperContestComboSerializer(
|
|
super_before_objects, many=True, context=self.context
|
|
).data
|
|
super_after_objects = SuperContestCombo.objects.filter(second_move=obj)
|
|
super_after_data = SuperContestComboSerializer(
|
|
super_after_objects, many=True, context=self.context
|
|
).data
|
|
|
|
details = None
|
|
|
|
if (
|
|
normal_before_data
|
|
or normal_after_data
|
|
or super_before_data
|
|
or super_after_data
|
|
):
|
|
details = OrderedDict()
|
|
details["normal"] = OrderedDict()
|
|
details["normal"]["use_before"] = None
|
|
details["normal"]["use_after"] = None
|
|
details["super"] = OrderedDict()
|
|
details["super"]["use_before"] = None
|
|
details["super"]["use_after"] = None
|
|
|
|
for combo in normal_before_data:
|
|
if details["normal"]["use_before"] is None:
|
|
details["normal"]["use_before"] = []
|
|
details["normal"]["use_before"].append(combo["second_move"])
|
|
|
|
for combo in normal_after_data:
|
|
if details["normal"]["use_after"] is None:
|
|
details["normal"]["use_after"] = []
|
|
details["normal"]["use_after"].append(combo["first_move"])
|
|
|
|
for combo in super_before_data:
|
|
if details["super"]["use_before"] is None:
|
|
details["super"]["use_before"] = []
|
|
details["super"]["use_before"].append(combo["second_move"])
|
|
|
|
for combo in super_after_data:
|
|
if details["super"]["use_after"] is None:
|
|
details["super"]["use_after"] = []
|
|
details["super"]["use_after"].append(combo["first_move"])
|
|
|
|
return details
|
|
|
|
@extend_schema_field(field={'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'effect', 'short_effect', 'language' ],
|
|
'properties': {
|
|
'effect': {
|
|
'type': 'string',
|
|
'example': 'Inflicts [regular damage]{mechanic:regular-damage}.'
|
|
},
|
|
'short_effect': {
|
|
'type': 'string',
|
|
'example': 'Inflicts regular damage with no additional effect.'
|
|
},
|
|
'language': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'en'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/language/9/'
|
|
}
|
|
}
|
|
}
|
|
},
|
|
},
|
|
})
|
|
def get_effect_text(self, obj):
|
|
effect_texts = MoveEffectEffectText.objects.filter(move_effect=obj.move_effect)
|
|
data = MoveEffectEffectTextSerializer(
|
|
effect_texts, many=True, context=self.context
|
|
).data
|
|
if len(data) > 0:
|
|
for key, value in data[0].items():
|
|
if "$effect_chance%" in value:
|
|
data[0][key] = value.replace(
|
|
"$effect_chance", f"{obj.move_effect_chance}"
|
|
)
|
|
|
|
return data
|
|
|
|
@extend_schema_field(field={'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'effect_entries', 'version_group' ],
|
|
'properties': {
|
|
'effect_entries': {
|
|
'type': 'array',
|
|
'items': {
|
|
'type': 'object',
|
|
'required': [ 'effect', 'language' ],
|
|
'properties': {
|
|
'effect': {
|
|
'type': 'string',
|
|
'example': 'Hits Pokémon under the effects of dig and fly.'
|
|
},
|
|
'language': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'en'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/language/9/'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
'version_group': {
|
|
'type': 'object',
|
|
'required': [ 'name', 'url' ],
|
|
'properties': {
|
|
'name': {
|
|
'type': 'string',
|
|
'example': 'gold-silver'
|
|
},
|
|
'url': {
|
|
'type': 'string',
|
|
'format': 'uri',
|
|
'example': 'https://pokeapi.co/api/v2/version-group/3/'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
})
|
|
def get_effect_change_text(self, obj):
|
|
effect_changes = MoveEffectChange.objects.filter(move_effect=obj.move_effect)
|
|
data = MoveEffectChangeSerializer(
|
|
effect_changes, many=True, context=self.context
|
|
).data
|
|
|
|
return data
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_move_stat_change(self, obj):
|
|
stat_change_objects = MoveMetaStatChange.objects.filter(move=obj)
|
|
stat_changes = MoveMetaStatChangeSerializer(
|
|
stat_change_objects, many=True, context=self.context
|
|
).data
|
|
|
|
for change in stat_changes:
|
|
del change["move"]
|
|
|
|
return stat_changes
|
|
|
|
|
|
##########################
|
|
# PAL PARK SERIALIZERS #
|
|
##########################
|
|
|
|
|
|
class PalParkSerializer(serializers.ModelSerializer):
|
|
area = PalParkAreaSummarySerializer(read_only=True, source="pal_park_area")
|
|
pokemon_species = PokemonSpeciesSummarySerializer()
|
|
|
|
class Meta:
|
|
model = PalPark
|
|
fields = ("base_score", "rate", "area", "pokemon_species")
|
|
|
|
|
|
class PalParkAreaNameSerializer(serializers.HyperlinkedModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = PalParkAreaName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class PalParkAreaDetailSerializer(serializers.ModelSerializer):
|
|
names = PalParkAreaNameSerializer(
|
|
many=True, read_only=True, source="palparkareaname"
|
|
)
|
|
pokemon_encounters = serializers.SerializerMethodField("get_encounters")
|
|
|
|
class Meta:
|
|
model = PalParkArea
|
|
fields = ("id", "name", "names", "pokemon_encounters")
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_encounters(self, obj):
|
|
pal_park_objects = PalPark.objects.filter(pal_park_area=obj)
|
|
parks = PalParkSerializer(
|
|
pal_park_objects, many=True, context=self.context
|
|
).data
|
|
encounters = []
|
|
|
|
for encounter in parks:
|
|
del encounter["area"]
|
|
encounters.append(encounter)
|
|
|
|
return encounters
|
|
|
|
|
|
###############################
|
|
# POKEMON COLOR SERIALIZERS #
|
|
###############################
|
|
|
|
|
|
class PokemonColorNameSerializer(serializers.HyperlinkedModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = PokemonColorName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class PokemonColorDetailSerializer(serializers.ModelSerializer):
|
|
names = PokemonColorNameSerializer(
|
|
many=True, read_only=True, source="pokemoncolorname"
|
|
)
|
|
pokemon_species = PokemonSpeciesSummarySerializer(
|
|
many=True, read_only=True, source="pokemonspecies"
|
|
)
|
|
|
|
class Meta:
|
|
model = PokemonColor
|
|
fields = ("id", "name", "names", "pokemon_species")
|
|
|
|
|
|
##############################
|
|
# POKEMON FORM SERIALIZERS #
|
|
##############################
|
|
class PokemonFormSpritesSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = PokemonFormSprites
|
|
fields = ("sprites",)
|
|
|
|
|
|
class PokemonFormNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = PokemonFormName
|
|
fields = ("name", "pokemon_name", "language")
|
|
|
|
|
|
class PokemonFormDetailSerializer(serializers.ModelSerializer):
|
|
pokemon = PokemonSummarySerializer()
|
|
version_group = VersionGroupSummarySerializer()
|
|
sprites = serializers.SerializerMethodField("get_pokemon_form_sprites")
|
|
form_names = serializers.SerializerMethodField("get_pokemon_form_names")
|
|
names = serializers.SerializerMethodField("get_pokemon_form_pokemon_names")
|
|
types = serializers.SerializerMethodField("get_pokemon_form_types")
|
|
|
|
class Meta:
|
|
model = PokemonForm
|
|
fields = (
|
|
"id",
|
|
"name",
|
|
"order",
|
|
"form_order",
|
|
"is_default",
|
|
"is_battle_only",
|
|
"is_mega",
|
|
"form_name",
|
|
"pokemon",
|
|
"sprites",
|
|
"version_group",
|
|
"form_names",
|
|
"names",
|
|
"types",
|
|
)
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_pokemon_form_names(self, obj):
|
|
form_results = PokemonFormName.objects.filter(
|
|
pokemon_form=obj, name__regex=".+"
|
|
)
|
|
form_serializer = PokemonFormNameSerializer(
|
|
form_results, many=True, context=self.context
|
|
)
|
|
|
|
data = form_serializer.data
|
|
|
|
for name in data:
|
|
del name["pokemon_name"]
|
|
|
|
return data
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_pokemon_form_pokemon_names(self, obj):
|
|
form_results = PokemonFormName.objects.filter(
|
|
pokemon_form=obj, pokemon_name__regex=".+"
|
|
)
|
|
form_serializer = PokemonFormNameSerializer(
|
|
form_results, many=True, context=self.context
|
|
)
|
|
|
|
data = form_serializer.data
|
|
|
|
for name in data:
|
|
name["name"] = name["pokemon_name"]
|
|
del name["pokemon_name"]
|
|
|
|
return data
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_pokemon_form_sprites(self, obj):
|
|
sprites_object = PokemonFormSprites.objects.get(pokemon_form_id=obj)
|
|
return sprites_object.sprites
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_pokemon_form_types(self, obj):
|
|
form_type_objects = PokemonFormType.objects.filter(pokemon_form=obj)
|
|
form_types = PokemonFormTypeSerializer(
|
|
form_type_objects, many=True, context=self.context
|
|
).data
|
|
|
|
for form_type in form_types:
|
|
del form_type["pokemon_form"]
|
|
|
|
# defer to parent Pokemon's types if no form-specific types
|
|
if form_types == []:
|
|
pokemon_object = Pokemon.objects.get(id=obj.pokemon_id)
|
|
pokemon_type_objects = PokemonType.objects.filter(pokemon=pokemon_object)
|
|
form_types = PokemonTypeSerializer(
|
|
pokemon_type_objects, many=True, context=self.context
|
|
).data
|
|
|
|
for form_type in form_types:
|
|
del form_type["pokemon"]
|
|
|
|
return form_types
|
|
|
|
|
|
#################################
|
|
# POKEMON HABITAT SERIALIZERS #
|
|
#################################
|
|
|
|
|
|
class PokemonHabitatNameSerializer(serializers.HyperlinkedModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = PokemonHabitatName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class PokemonHabitatDetailSerializer(serializers.ModelSerializer):
|
|
names = PokemonHabitatNameSerializer(
|
|
many=True, read_only=True, source="pokemonhabitatname"
|
|
)
|
|
pokemon_species = PokemonSpeciesSummarySerializer(
|
|
many=True, read_only=True, source="pokemonspecies"
|
|
)
|
|
|
|
class Meta:
|
|
model = PokemonHabitat
|
|
fields = ("id", "name", "names", "pokemon_species")
|
|
|
|
|
|
##############################
|
|
# POKEMON MOVE SERIALIZERS #
|
|
##############################
|
|
|
|
|
|
class MoveLearnMethodNameSerializer(serializers.HyperlinkedModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = MoveLearnMethodName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class MoveLearnMethodDescriptionSerializer(serializers.HyperlinkedModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = MoveLearnMethodDescription
|
|
fields = ("description", "language")
|
|
|
|
|
|
class MoveLearnMethodDetailSerializer(serializers.ModelSerializer):
|
|
names = MoveLearnMethodNameSerializer(
|
|
many=True, read_only=True, source="movelearnmethodname"
|
|
)
|
|
descriptions = MoveLearnMethodDescriptionSerializer(
|
|
many=True, read_only=True, source="movelearnmethoddescription"
|
|
)
|
|
version_groups = serializers.SerializerMethodField("get_method_version_groups")
|
|
|
|
class Meta:
|
|
model = MoveLearnMethod
|
|
fields = ("id", "name", "names", "descriptions", "version_groups")
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_method_version_groups(self, obj):
|
|
version_group_objects = VersionGroupMoveLearnMethod.objects.filter(
|
|
move_learn_method=obj
|
|
)
|
|
version_group_data = VersionGroupMoveLearnMethodSerializer(
|
|
version_group_objects, many=True, context=self.context
|
|
).data
|
|
groups = []
|
|
|
|
for vg in version_group_data:
|
|
groups.append(vg["version_group"])
|
|
|
|
return groups
|
|
|
|
|
|
# https://stackoverflow.com/a/45987450/3482533
|
|
class PokemonMoveSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = PokemonMove
|
|
fields = "__all__"
|
|
|
|
|
|
###############################
|
|
# POKEMON SHAPE SERIALIZERS #
|
|
###############################
|
|
class PokemonShapeNameSerializer(serializers.HyperlinkedModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = PokemonShapeName
|
|
fields = ("name", "awesome_name", "language")
|
|
|
|
|
|
class PokemonShapeDetailSerializer(serializers.ModelSerializer):
|
|
names = serializers.SerializerMethodField("get_shape_names")
|
|
awesome_names = serializers.SerializerMethodField("get_shape_awesome_names")
|
|
pokemon_species = PokemonSpeciesSummarySerializer(
|
|
many=True, read_only=True, source="pokemonspecies"
|
|
)
|
|
|
|
class Meta:
|
|
model = PokemonShape
|
|
fields = ("id", "name", "awesome_names", "names", "pokemon_species")
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_shape_names(self, obj):
|
|
results = PokemonShapeName.objects.filter(pokemon_shape_id=obj)
|
|
serializer = PokemonShapeNameSerializer(
|
|
results, many=True, context=self.context
|
|
)
|
|
data = serializer.data
|
|
|
|
for entry in data:
|
|
del entry["awesome_name"]
|
|
|
|
return data
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_shape_awesome_names(self, obj):
|
|
results = PokemonShapeName.objects.filter(pokemon_shape_id=obj)
|
|
serializer = PokemonShapeNameSerializer(
|
|
results, many=True, context=self.context
|
|
)
|
|
data = serializer.data
|
|
|
|
for entry in data:
|
|
del entry["name"]
|
|
|
|
return data
|
|
|
|
|
|
##############################
|
|
# POKEMON ITEM SERIALIZERS #
|
|
##############################
|
|
class PokemonItemSerializer(serializers.ModelSerializer):
|
|
version = VersionSummarySerializer()
|
|
item = ItemSummarySerializer()
|
|
|
|
class Meta:
|
|
model = PokemonItem
|
|
fields = ("rarity", "item", "version")
|
|
|
|
|
|
##############################
|
|
# POKEMON STAT SERIALIZERS #
|
|
##############################
|
|
class PokemonStatSerializer(serializers.ModelSerializer):
|
|
stat = StatSummarySerializer()
|
|
|
|
class Meta:
|
|
model = PokemonStat
|
|
fields = ("base_stat", "effort", "stat")
|
|
|
|
|
|
#########################
|
|
# POKEMON SERIALIZERS #
|
|
#########################
|
|
|
|
|
|
class PokemonGameIndexSerializer(serializers.ModelSerializer):
|
|
version = VersionSummarySerializer()
|
|
|
|
class Meta:
|
|
model = PokemonGameIndex
|
|
fields = ("game_index", "version")
|
|
|
|
|
|
class PokemonDetailSerializer(serializers.ModelSerializer):
|
|
abilities = serializers.SerializerMethodField("get_pokemon_abilities")
|
|
past_abilities = serializers.SerializerMethodField("get_past_pokemon_abilities")
|
|
game_indices = PokemonGameIndexSerializer(
|
|
many=True, read_only=True, source="pokemongameindex"
|
|
)
|
|
moves = serializers.SerializerMethodField("get_pokemon_moves")
|
|
species = PokemonSpeciesSummarySerializer(source="pokemon_species")
|
|
stats = PokemonStatSerializer(many=True, read_only=True, source="pokemonstat")
|
|
types = serializers.SerializerMethodField("get_pokemon_types")
|
|
past_types = serializers.SerializerMethodField("get_past_pokemon_types")
|
|
forms = PokemonFormSummarySerializer(
|
|
many=True, read_only=True, source="pokemonform"
|
|
)
|
|
held_items = serializers.SerializerMethodField("get_pokemon_held_items")
|
|
location_area_encounters = serializers.SerializerMethodField("get_encounters")
|
|
sprites = serializers.SerializerMethodField("get_pokemon_sprites")
|
|
cries = serializers.SerializerMethodField("get_pokemon_cries")
|
|
|
|
class Meta:
|
|
model = Pokemon
|
|
fields = (
|
|
"id",
|
|
"name",
|
|
"base_experience",
|
|
"height",
|
|
"is_default",
|
|
"order",
|
|
"weight",
|
|
"abilities",
|
|
"past_abilities",
|
|
"forms",
|
|
"game_indices",
|
|
"held_items",
|
|
"location_area_encounters",
|
|
"moves",
|
|
"species",
|
|
"sprites",
|
|
"cries",
|
|
"stats",
|
|
"types",
|
|
"past_types",
|
|
)
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_pokemon_sprites(self, obj):
|
|
sprites_object = PokemonSprites.objects.get(pokemon_id=obj)
|
|
return sprites_object.sprites
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_pokemon_cries(self, obj):
|
|
cries_object = PokemonCries.objects.get(pokemon_id=obj)
|
|
return cries_object.cries
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_pokemon_moves(self, obj):
|
|
version_objects = VersionGroup.objects.all()
|
|
version_data = VersionGroupSummarySerializer(
|
|
version_objects, many=True, context=self.context
|
|
).data
|
|
method_objects = MoveLearnMethod.objects.all()
|
|
method_data = MoveLearnMethodSummarySerializer(
|
|
method_objects, many=True, context=self.context
|
|
).data
|
|
|
|
# Get moves related to this pokemon and pull out unique Move IDs.
|
|
# Note that it's important to order by the same column we're using to
|
|
# determine if the entries are unique. Otherwise distinct() will
|
|
# return apparent duplicates.
|
|
|
|
pokemon_moves = PokemonMove.objects.filter(pokemon_id=obj).order_by("move_id")
|
|
move_ids = pokemon_moves.values("move_id").distinct()
|
|
move_list = []
|
|
|
|
for id in move_ids:
|
|
pokemon_move_details = OrderedDict()
|
|
|
|
# Get each Unique Move by ID
|
|
move_object = Move.objects.get(pk=id["move_id"])
|
|
move_data = MoveSummarySerializer(move_object, context=self.context).data
|
|
pokemon_move_details["move"] = move_data
|
|
|
|
# Get Versions and Move Methods associated with each unique move
|
|
pokemon_move_objects = pokemon_moves.filter(move_id=id["move_id"])
|
|
serializer = PokemonMoveSerializer(
|
|
pokemon_move_objects, many=True, context=self.context
|
|
)
|
|
pokemon_move_details["version_group_details"] = []
|
|
|
|
for move in serializer.data:
|
|
version_detail = OrderedDict()
|
|
|
|
version_detail["level_learned_at"] = move["level"]
|
|
version_detail["version_group"] = version_data[
|
|
move["version_group"] - 1
|
|
]
|
|
version_detail["move_learn_method"] = method_data[
|
|
move["move_learn_method"] - 1
|
|
]
|
|
|
|
pokemon_move_details["version_group_details"].append(version_detail)
|
|
|
|
move_list.append(pokemon_move_details)
|
|
|
|
return move_list
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_pokemon_held_items(self, obj):
|
|
# Get items related to this pokemon and pull out unique Item IDs
|
|
pokemon_items = PokemonItem.objects.filter(pokemon_id=obj).order_by("item_id")
|
|
item_ids = pokemon_items.values("item_id").distinct()
|
|
item_list = []
|
|
|
|
for id in item_ids:
|
|
pokemon_item_details = OrderedDict()
|
|
|
|
# Get each Unique Item by ID
|
|
item_object = Item.objects.get(pk=id["item_id"])
|
|
item_data = ItemSummarySerializer(item_object, context=self.context).data
|
|
pokemon_item_details["item"] = item_data
|
|
|
|
# Get Versions associated with each unique item
|
|
pokemon_item_objects = pokemon_items.filter(item_id=id["item_id"])
|
|
serializer = PokemonItemSerializer(
|
|
pokemon_item_objects, many=True, context=self.context
|
|
)
|
|
pokemon_item_details["version_details"] = []
|
|
|
|
for item in serializer.data:
|
|
version_detail = OrderedDict()
|
|
|
|
version_detail["rarity"] = item["rarity"]
|
|
version_detail["version"] = item["version"]
|
|
|
|
pokemon_item_details["version_details"].append(version_detail)
|
|
|
|
item_list.append(pokemon_item_details)
|
|
|
|
return item_list
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_pokemon_abilities(self, obj):
|
|
pokemon_ability_objects = PokemonAbility.objects.filter(pokemon=obj)
|
|
data = PokemonAbilitySerializer(
|
|
pokemon_ability_objects, many=True, context=self.context
|
|
).data
|
|
abilities = []
|
|
|
|
for ability in data:
|
|
del ability["pokemon"]
|
|
abilities.append(ability)
|
|
|
|
return abilities
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_past_pokemon_abilities(self, obj):
|
|
pokemon_past_ability_objects = PokemonAbilityPast.objects.filter(pokemon=obj)
|
|
pokemon_past_abilities = PokemonAbilityPastSerializer(
|
|
pokemon_past_ability_objects, many=True, context=self.context
|
|
).data
|
|
|
|
# post-process to the form we want
|
|
current_generation = ""
|
|
past_obj = {}
|
|
final_data = []
|
|
for pokemon_past_ability in pokemon_past_abilities:
|
|
del pokemon_past_ability["pokemon"]
|
|
|
|
generation = pokemon_past_ability["generation"]["name"]
|
|
if generation != current_generation:
|
|
current_generation = generation
|
|
past_obj = {}
|
|
|
|
# create past abilities object for this generation
|
|
past_obj["generation"] = pokemon_past_ability["generation"]
|
|
del pokemon_past_ability["generation"]
|
|
|
|
# create abilities array
|
|
past_obj["abilities"] = [pokemon_past_ability]
|
|
|
|
# add to past abilities array
|
|
final_data.append(past_obj)
|
|
|
|
else:
|
|
# add to existing array for this generation
|
|
del pokemon_past_ability["generation"]
|
|
past_obj["abilities"].append(pokemon_past_ability)
|
|
|
|
return final_data
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_pokemon_types(self, obj):
|
|
poke_type_objects = PokemonType.objects.filter(pokemon=obj)
|
|
poke_types = PokemonTypeSerializer(
|
|
poke_type_objects, many=True, context=self.context
|
|
).data
|
|
|
|
for poke_type in poke_types:
|
|
del poke_type["pokemon"]
|
|
|
|
return poke_types
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_past_pokemon_types(self, obj):
|
|
poke_past_type_objects = PokemonTypePast.objects.filter(pokemon=obj)
|
|
poke_past_types = PokemonTypePastSerializer(
|
|
poke_past_type_objects, many=True, context=self.context
|
|
).data
|
|
|
|
# post-process to the form we want
|
|
current_generation = ""
|
|
past_obj = {}
|
|
final_data = []
|
|
for poke_past_type in poke_past_types:
|
|
del poke_past_type["pokemon"]
|
|
|
|
generation = poke_past_type["generation"]["name"]
|
|
if generation != current_generation:
|
|
current_generation = generation
|
|
past_obj = {}
|
|
|
|
# create past types object for this generation
|
|
past_obj["generation"] = poke_past_type["generation"]
|
|
del poke_past_type["generation"]
|
|
|
|
# create types array
|
|
past_obj["types"] = [poke_past_type]
|
|
|
|
# add to past types array
|
|
final_data.append(past_obj)
|
|
|
|
else:
|
|
# add to existing array for this generation
|
|
del poke_past_type["generation"]
|
|
past_obj["types"].append(poke_past_type)
|
|
|
|
return final_data
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_encounters(self, obj):
|
|
return reverse("pokemon_encounters", kwargs={"pokemon_id": obj.pk})
|
|
|
|
|
|
#################################
|
|
# POKEMON SPECIES SERIALIZERS #
|
|
#################################
|
|
class EvolutionTriggerNameSerializer(serializers.HyperlinkedModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = EvolutionTriggerName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class EvolutionTriggerDetailSerializer(serializers.HyperlinkedModelSerializer):
|
|
names = EvolutionTriggerNameSerializer(
|
|
many=True, read_only=True, source="evolutiontriggername"
|
|
)
|
|
pokemon_species = serializers.SerializerMethodField("get_species")
|
|
|
|
class Meta:
|
|
model = EvolutionTrigger
|
|
fields = ("id", "name", "names", "pokemon_species")
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_species(self, obj):
|
|
evo_objects = PokemonEvolution.objects.filter(evolution_trigger=obj)
|
|
species_list = []
|
|
species_names = set()
|
|
|
|
for evo in evo_objects:
|
|
species = PokemonSpeciesSummarySerializer(
|
|
evo.evolved_species, context=self.context
|
|
).data
|
|
if species["name"] not in species_names:
|
|
species_list.append(species)
|
|
species_names.add(species["name"])
|
|
|
|
return species_list
|
|
|
|
|
|
class PokemonSpeciesDescriptionSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = PokemonSpeciesDescription
|
|
fields = ("description", "language")
|
|
|
|
|
|
class PokemonSpeciesFlavorTextSerializer(serializers.ModelSerializer):
|
|
flavor_text = serializers.CharField()
|
|
language = LanguageSummarySerializer()
|
|
version = VersionSummarySerializer()
|
|
|
|
class Meta:
|
|
model = PokemonSpeciesFlavorText
|
|
fields = ("flavor_text", "language", "version")
|
|
|
|
|
|
class PokemonSpeciesNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = PokemonSpeciesName
|
|
fields = ("name", "genus", "language")
|
|
|
|
|
|
class PokemonSpeciesEvolutionSerializer(serializers.ModelSerializer):
|
|
"""
|
|
This is here purely to help build pokemon evolution chains
|
|
"""
|
|
|
|
class Meta:
|
|
model = PokemonSpecies
|
|
fields = ("name", "id", "evolves_from_species", "is_baby")
|
|
|
|
|
|
class PokemonSpeciesDetailSerializer(serializers.ModelSerializer):
|
|
names = serializers.SerializerMethodField("get_pokemon_names")
|
|
form_descriptions = PokemonSpeciesDescriptionSerializer(
|
|
many=True, read_only=True, source="pokemonspeciesdescription"
|
|
)
|
|
pokedex_numbers = PokemonDexEntrySerializer(
|
|
many=True, read_only=True, source="pokemondexnumber"
|
|
)
|
|
egg_groups = serializers.SerializerMethodField("get_pokemon_egg_groups")
|
|
flavor_text_entries = PokemonSpeciesFlavorTextSerializer(
|
|
many=True, read_only=True, source="pokemonspeciesflavortext"
|
|
)
|
|
genera = serializers.SerializerMethodField("get_pokemon_genera")
|
|
generation = GenerationSummarySerializer()
|
|
growth_rate = GrowthRateSummarySerializer()
|
|
color = PokemonColorSummarySerializer(source="pokemon_color")
|
|
habitat = PokemonHabitatSummarySerializer(source="pokemon_habitat")
|
|
shape = PokemonShapeSummarySerializer(source="pokemon_shape")
|
|
evolves_from_species = PokemonSpeciesSummarySerializer()
|
|
varieties = serializers.SerializerMethodField("get_pokemon_varieties")
|
|
evolution_chain = EvolutionChainSummarySerializer()
|
|
pal_park_encounters = serializers.SerializerMethodField("get_encounters")
|
|
|
|
class Meta:
|
|
model = PokemonSpecies
|
|
fields = (
|
|
"id",
|
|
"name",
|
|
"order",
|
|
"gender_rate",
|
|
"capture_rate",
|
|
"base_happiness",
|
|
"is_baby",
|
|
"is_legendary",
|
|
"is_mythical",
|
|
"hatch_counter",
|
|
"has_gender_differences",
|
|
"forms_switchable",
|
|
"growth_rate",
|
|
"pokedex_numbers",
|
|
"egg_groups",
|
|
"color",
|
|
"shape",
|
|
"evolves_from_species",
|
|
"evolution_chain",
|
|
"habitat",
|
|
"generation",
|
|
"names",
|
|
"pal_park_encounters",
|
|
"form_descriptions",
|
|
"flavor_text_entries",
|
|
"genera",
|
|
"varieties",
|
|
)
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_pokemon_names(self, obj):
|
|
species_results = PokemonSpeciesName.objects.filter(pokemon_species=obj)
|
|
species_serializer = PokemonSpeciesNameSerializer(
|
|
species_results, many=True, context=self.context
|
|
)
|
|
|
|
data = species_serializer.data
|
|
|
|
for name in data:
|
|
del name["genus"]
|
|
|
|
return data
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_pokemon_genera(self, obj):
|
|
results = PokemonSpeciesName.objects.filter(pokemon_species=obj)
|
|
serializer = PokemonSpeciesNameSerializer(
|
|
results, many=True, context=self.context
|
|
)
|
|
data = serializer.data
|
|
genera = []
|
|
|
|
for entry in data:
|
|
if entry["genus"]:
|
|
del entry["name"]
|
|
genera.append(entry)
|
|
|
|
return genera
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_pokemon_egg_groups(self, obj):
|
|
results = PokemonEggGroup.objects.filter(pokemon_species=obj)
|
|
data = PokemonEggGroupSerializer(results, many=True, context=self.context).data
|
|
groups = []
|
|
for group in data:
|
|
groups.append(group["egg_group"])
|
|
|
|
return groups
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_pokemon_varieties(self, obj):
|
|
results = Pokemon.objects.filter(pokemon_species=obj)
|
|
summary_data = PokemonSummarySerializer(
|
|
results, many=True, context=self.context
|
|
).data
|
|
detail_data = PokemonDetailSerializer(
|
|
results, many=True, context=self.context
|
|
).data
|
|
|
|
varieties = []
|
|
|
|
for index, pokemon in enumerate(detail_data):
|
|
entry = OrderedDict()
|
|
entry["is_default"] = pokemon["is_default"]
|
|
entry["pokemon"] = summary_data[index]
|
|
varieties.append(entry)
|
|
|
|
return varieties
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_encounters(self, obj):
|
|
pal_park_objects = PalPark.objects.filter(pokemon_species=obj)
|
|
parks = PalParkSerializer(
|
|
pal_park_objects, many=True, context=self.context
|
|
).data
|
|
encounters = []
|
|
|
|
for encounter in parks:
|
|
del encounter["pokemon_species"]
|
|
encounters.append(encounter)
|
|
|
|
return encounters
|
|
|
|
|
|
class PokemonEvolutionSerializer(serializers.ModelSerializer):
|
|
item = ItemSummarySerializer(source="evolution_item")
|
|
held_item = ItemSummarySerializer()
|
|
known_move = MoveSummarySerializer()
|
|
known_move_type = TypeSummarySerializer()
|
|
party_species = PokemonSpeciesSummarySerializer()
|
|
party_type = TypeSummarySerializer()
|
|
trade_species = PokemonSpeciesSummarySerializer()
|
|
location = LocationSummarySerializer()
|
|
trigger = EvolutionTriggerSummarySerializer(source="evolution_trigger")
|
|
|
|
class Meta:
|
|
model = PokemonEvolution
|
|
fields = (
|
|
"item",
|
|
"trigger",
|
|
"gender",
|
|
"held_item",
|
|
"known_move",
|
|
"known_move_type",
|
|
"location",
|
|
"min_level",
|
|
"min_happiness",
|
|
"min_beauty",
|
|
"min_affection",
|
|
"needs_overworld_rain",
|
|
"party_species",
|
|
"party_type",
|
|
"relative_physical_stats",
|
|
"time_of_day",
|
|
"trade_species",
|
|
"turn_upside_down",
|
|
)
|
|
|
|
|
|
class EvolutionChainDetailSerializer(serializers.ModelSerializer):
|
|
baby_trigger_item = ItemSummarySerializer()
|
|
chain = serializers.SerializerMethodField("build_chain")
|
|
|
|
class Meta:
|
|
model = EvolutionChain
|
|
fields = ("id", "baby_trigger_item", "chain")
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def build_chain(self, obj):
|
|
chain_id = obj.id
|
|
|
|
pokemon_objects = PokemonSpecies.objects.filter(
|
|
evolution_chain_id=chain_id
|
|
).order_by("order")
|
|
summary_data = PokemonSpeciesSummarySerializer(
|
|
pokemon_objects, many=True, context=self.context
|
|
).data
|
|
ref_data = PokemonSpeciesEvolutionSerializer(
|
|
pokemon_objects, many=True, context=self.context
|
|
).data
|
|
|
|
# convert evolution data list to tree
|
|
evolution_tree = self.build_evolution_tree(ref_data)
|
|
|
|
# serialize chain recursively from tree
|
|
chain = self.build_chain_link_entry(evolution_tree, summary_data)
|
|
|
|
return chain
|
|
|
|
# converts a list of Pokemon species evolution data into a tree representing the evolution chain
|
|
def build_evolution_tree(self, species_evolution_data):
|
|
evolution_tree = OrderedDict()
|
|
evolution_tree["species"] = species_evolution_data[0]
|
|
evolution_tree["children"] = []
|
|
|
|
for species in species_evolution_data[1:]:
|
|
chain_link = OrderedDict()
|
|
chain_link["species"] = species
|
|
chain_link["children"] = []
|
|
|
|
evolves_from_species_id = chain_link["species"]["evolves_from_species"]
|
|
|
|
# find parent link by DFS
|
|
parent_link = evolution_tree
|
|
search_stack = [parent_link]
|
|
|
|
while len(search_stack) > 0:
|
|
l = search_stack.pop()
|
|
if l["species"]["id"] == evolves_from_species_id:
|
|
parent_link = l
|
|
break
|
|
|
|
# "left" to "right" requires reversing the list of children
|
|
search_stack += reversed(l["children"])
|
|
|
|
parent_link["children"].append(chain_link)
|
|
|
|
return evolution_tree
|
|
|
|
# serializes an evolution chain link recursively
|
|
# chain_link is a tree representing an evolution chain
|
|
def build_chain_link_entry(self, chain_link, summary_data):
|
|
entry = OrderedDict()
|
|
evolution_data = None
|
|
|
|
species = chain_link["species"]
|
|
if species["evolves_from_species"]:
|
|
evolution_object = PokemonEvolution.objects.filter(
|
|
evolved_species=species["id"]
|
|
)
|
|
|
|
evolution_data = PokemonEvolutionSerializer(
|
|
evolution_object, many=True, context=self.context
|
|
).data
|
|
|
|
entry["is_baby"] = species["is_baby"]
|
|
|
|
species_summary = next(x for x in summary_data if x["name"] == species["name"])
|
|
entry["species"] = species_summary
|
|
|
|
entry["evolution_details"] = evolution_data or []
|
|
|
|
evolves_to = [
|
|
self.build_chain_link_entry(c, summary_data) for c in chain_link["children"]
|
|
]
|
|
entry["evolves_to"] = evolves_to
|
|
|
|
return entry
|
|
|
|
|
|
class PokemonDexNumberSerializer(serializers.ModelSerializer):
|
|
entry_number = serializers.IntegerField(source="pokedex_number")
|
|
pokemon_species = PokemonSpeciesSummarySerializer()
|
|
|
|
class Meta:
|
|
model = PokemonDexNumber
|
|
fields = ("pokedex", "entry_number", "pokemon_species")
|
|
|
|
|
|
############################
|
|
# POKEATHLON SERIALIZERS #
|
|
############################
|
|
class PokeathlonStatNameSerializer(serializers.HyperlinkedModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = PokeathlonStatName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class PokeathlonStatDetailSerializer(serializers.HyperlinkedModelSerializer):
|
|
names = PokeathlonStatNameSerializer(
|
|
many=True, read_only=True, source="pokeathlonstatname"
|
|
)
|
|
affecting_natures = serializers.SerializerMethodField("get_natures_that_affect")
|
|
|
|
class Meta:
|
|
model = PokeathlonStat
|
|
fields = ("id", "name", "affecting_natures", "names")
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_natures_that_affect(self, obj):
|
|
stat_change_objects = NaturePokeathlonStat.objects.filter(pokeathlon_stat=obj)
|
|
stat_changes = NaturePokeathlonStatSerializer(
|
|
stat_change_objects, many=True, context=self.context
|
|
).data
|
|
changes = OrderedDict([("increase", []), ("decrease", [])])
|
|
|
|
for change in stat_changes:
|
|
del change["pokeathlon_stat"]
|
|
if change["max_change"] > 0:
|
|
changes["increase"].append(change)
|
|
else:
|
|
changes["decrease"].append(change)
|
|
|
|
return changes
|
|
|
|
|
|
#########################
|
|
# POKEDEX SERIALIZERS #
|
|
#########################
|
|
class PokedexNameSerializer(serializers.HyperlinkedModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = PokedexName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class PokedexDescriptionSerializer(serializers.HyperlinkedModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = PokedexDescription
|
|
fields = ("description", "language")
|
|
|
|
|
|
class PokedexDetailSerializer(serializers.ModelSerializer):
|
|
region = RegionSummarySerializer()
|
|
names = PokedexNameSerializer(many=True, read_only=True, source="pokedexname")
|
|
descriptions = PokedexDescriptionSerializer(
|
|
many=True, read_only=True, source="pokedexdescription"
|
|
)
|
|
pokemon_entries = serializers.SerializerMethodField("get_pokedex_entries")
|
|
version_groups = serializers.SerializerMethodField("get_pokedex_version_groups")
|
|
|
|
class Meta:
|
|
model = Pokedex
|
|
fields = (
|
|
"id",
|
|
"name",
|
|
"is_main_series",
|
|
"descriptions",
|
|
"names",
|
|
"pokemon_entries",
|
|
"region",
|
|
"version_groups",
|
|
)
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_pokedex_entries(self, obj):
|
|
results = PokemonDexNumber.objects.filter(pokedex=obj).order_by(
|
|
"pokedex_number"
|
|
)
|
|
serializer = PokemonDexNumberSerializer(
|
|
results, many=True, context=self.context
|
|
)
|
|
data = serializer.data
|
|
|
|
for entry in data:
|
|
del entry["pokedex"]
|
|
|
|
return data
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_pokedex_version_groups(self, obj):
|
|
dex_group_objects = PokedexVersionGroup.objects.filter(pokedex=obj)
|
|
dex_groups = PokedexVersionGroupSerializer(
|
|
dex_group_objects, many=True, context=self.context
|
|
).data
|
|
results = []
|
|
|
|
for dex_group in dex_groups:
|
|
results.append(dex_group["version_group"])
|
|
|
|
return results
|
|
|
|
|
|
#########################
|
|
# VERSION SERIALIZERS #
|
|
#########################
|
|
class VersionNameSerializer(serializers.ModelSerializer):
|
|
language = LanguageSummarySerializer()
|
|
|
|
class Meta:
|
|
model = VersionName
|
|
fields = ("name", "language")
|
|
|
|
|
|
class VersionDetailSerializer(serializers.ModelSerializer):
|
|
"""
|
|
Should have a link to Version Group info but the Circular
|
|
dependency and compilation order fight eachother and I'm
|
|
not sure how to add anything other than a hyperlink
|
|
"""
|
|
|
|
names = VersionNameSerializer(many=True, read_only=True, source="versionname")
|
|
version_group = VersionGroupSummarySerializer()
|
|
|
|
class Meta:
|
|
model = Version
|
|
fields = ("id", "name", "names", "version_group")
|
|
|
|
|
|
class VersionGroupDetailSerializer(serializers.ModelSerializer):
|
|
generation = GenerationSummarySerializer()
|
|
versions = VersionSummarySerializer(many=True, read_only=True, source="version")
|
|
regions = serializers.SerializerMethodField("get_version_group_regions")
|
|
move_learn_methods = serializers.SerializerMethodField("get_learn_methods")
|
|
pokedexes = serializers.SerializerMethodField("get_version_groups_pokedexes")
|
|
|
|
class Meta:
|
|
model = VersionGroup
|
|
fields = (
|
|
"id",
|
|
"name",
|
|
"order",
|
|
"generation",
|
|
"move_learn_methods",
|
|
"pokedexes",
|
|
"regions",
|
|
"versions",
|
|
)
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_version_group_regions(self, obj):
|
|
vg_regions = VersionGroupRegion.objects.filter(version_group=obj)
|
|
data = VersionGroupRegionSerializer(
|
|
vg_regions, many=True, context=self.context
|
|
).data
|
|
regions = []
|
|
|
|
for region in data:
|
|
regions.append(region["region"])
|
|
|
|
return regions
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_learn_methods(self, obj):
|
|
learn_method_objects = VersionGroupMoveLearnMethod.objects.filter(
|
|
version_group=obj
|
|
)
|
|
learn_method_data = VersionGroupMoveLearnMethodSerializer(
|
|
learn_method_objects, many=True, context=self.context
|
|
).data
|
|
methods = []
|
|
|
|
for method in learn_method_data:
|
|
methods.append(method["move_learn_method"])
|
|
|
|
return methods
|
|
|
|
@extend_schema_field(OpenApiTypes.OBJECT)
|
|
def get_version_groups_pokedexes(self, obj):
|
|
dex_group_objects = PokedexVersionGroup.objects.filter(version_group=obj)
|
|
dex_groups = PokedexVersionGroupSerializer(
|
|
dex_group_objects, many=True, context=self.context
|
|
).data
|
|
results = []
|
|
|
|
for dex_group in dex_groups:
|
|
results.append(dex_group["pokedex"])
|
|
|
|
return results
|