mirror of
https://github.com/PokeAPI/pokeapi
synced 2024-11-22 11:23:13 +00:00
Merge pull request #457 from phrasmotica/past-pokemon-types
This commit is contained in:
commit
e2e43d8bda
7 changed files with 258 additions and 59 deletions
|
@ -2021,6 +2021,16 @@ def _build_pokemons():
|
|||
|
||||
build_generic((PokemonType,), "pokemon_types.csv", csv_record_to_objects)
|
||||
|
||||
def csv_record_to_objects(info):
|
||||
yield PokemonTypePast(
|
||||
pokemon_id=int(info[0]),
|
||||
generation_id=int(info[1]),
|
||||
type_id=int(info[2]),
|
||||
slot=int(info[3]),
|
||||
)
|
||||
|
||||
build_generic((PokemonTypePast,), "pokemon_types_past.csv", csv_record_to_objects)
|
||||
|
||||
|
||||
###############
|
||||
# ENCOUNTER #
|
||||
|
|
37
data/v2/csv/pokemon_types_past.csv
Normal file
37
data/v2/csv/pokemon_types_past.csv
Normal file
|
@ -0,0 +1,37 @@
|
|||
pokemon_id,generation_id,type_id,slot
|
||||
35,5,1,1
|
||||
36,5,1,1
|
||||
39,5,1,1
|
||||
40,5,1,1
|
||||
81,1,13,1
|
||||
82,1,13,1
|
||||
122,5,14,1
|
||||
173,5,1,1
|
||||
174,5,1,1
|
||||
175,5,1,1
|
||||
176,5,1,1
|
||||
176,5,3,2
|
||||
183,5,11,1
|
||||
184,5,11,1
|
||||
209,5,1,1
|
||||
210,5,1,1
|
||||
280,5,14,1
|
||||
281,5,14,1
|
||||
282,5,14,1
|
||||
298,5,1,1
|
||||
303,5,9,1
|
||||
439,5,14,1
|
||||
468,5,1,1
|
||||
468,5,3,2
|
||||
546,5,12,1
|
||||
547,5,12,1
|
||||
10008,4,13,1
|
||||
10008,4,8,2
|
||||
10009,4,13,1
|
||||
10009,4,8,2
|
||||
10010,4,13,1
|
||||
10010,4,8,2
|
||||
10011,4,13,1
|
||||
10011,4,8,2
|
||||
10012,4,13,1
|
||||
10012,4,8,2
|
|
|
@ -2266,106 +2266,96 @@ Pokémon are the creatures that inhabit the world of the pokemon games. They can
|
|||
|
||||
```json
|
||||
{
|
||||
"id": 12,
|
||||
"name": "butterfree",
|
||||
"base_experience": 178,
|
||||
"height": 11,
|
||||
"id": 35,
|
||||
"name": "clefairy",
|
||||
"base_experience": 113,
|
||||
"height": 6,
|
||||
"is_default": true,
|
||||
"order": 16,
|
||||
"weight": 320,
|
||||
"order": 56,
|
||||
"weight": 75,
|
||||
"abilities": [{
|
||||
"is_hidden": true,
|
||||
"slot": 3,
|
||||
"ability": {
|
||||
"name": "tinted-lens",
|
||||
"url": "http://pokeapi.co/api/v2/ability/110/"
|
||||
"name": "friend-guard",
|
||||
"url": "https://pokeapi.co/api/v2/ability/132/"
|
||||
}
|
||||
}],
|
||||
"forms": [{
|
||||
"name": "butterfree",
|
||||
"url": "http://pokeapi.co/api/v2/pokemon-form/12/"
|
||||
"name": "clefairy",
|
||||
"url": "https://pokeapi.co/api/v2/pokemon-form/35/"
|
||||
}],
|
||||
"game_indices": [{
|
||||
"game_index": 12,
|
||||
"game_index": 35,
|
||||
"version": {
|
||||
"name": "white-2",
|
||||
"url": "http://pokeapi.co/api/v2/version/22/"
|
||||
"url": "https://pokeapi.co/api/v2/version/22/"
|
||||
}
|
||||
}],
|
||||
"held_items": [{
|
||||
"item": {
|
||||
"name": "silver-powder",
|
||||
"url": "http://pokeapi.co/api/v2/item/199/"
|
||||
"name": "moon-stone",
|
||||
"url": "https://pokeapi.co/api/v2/item/81/"
|
||||
},
|
||||
"version_details": [{
|
||||
"rarity": 5,
|
||||
"version": {
|
||||
"name": "y",
|
||||
"url": "http://pokeapi.co/api/v2/version/24/"
|
||||
}
|
||||
}]
|
||||
}],
|
||||
"location_area_encounters": [{
|
||||
"location_area": {
|
||||
"name": "kanto-route-2-south-towards-viridian-city",
|
||||
"url": "http://pokeapi.co/api/v2/location-area/296/"
|
||||
},
|
||||
"version_details": [{
|
||||
"max_chance": 10,
|
||||
"encounter_details": [{
|
||||
"min_level": 7,
|
||||
"max_level": 7,
|
||||
"condition_values": [{
|
||||
"name": "time-morning",
|
||||
"url": "http://pokeapi.co/api/v2/encounter-condition-value/3/"
|
||||
}],
|
||||
"chance": 5,
|
||||
"method": {
|
||||
"name": "walk",
|
||||
"url": "http://pokeapi.co/api/v2/encounter-method/1/"
|
||||
}
|
||||
}],
|
||||
"version": {
|
||||
"name": "heartgold",
|
||||
"url": "http://pokeapi.co/api/v2/version/15/"
|
||||
"name": "ruby",
|
||||
"url": "https://pokeapi.co/api/v2/version/7/"
|
||||
}
|
||||
}]
|
||||
}],
|
||||
"location_area_encounters": "/api/v2/pokemon/35/encounters",
|
||||
"moves": [{
|
||||
"move": {
|
||||
"name": "flash",
|
||||
"url": "http://pokeapi.co/api/v2/move/148/"
|
||||
"name": "pound",
|
||||
"url": "https://pokeapi.co/api/v2/move/1/"
|
||||
},
|
||||
"version_group_details": [{
|
||||
"level_learned_at": 0,
|
||||
"level_learned_at": 1,
|
||||
"version_group": {
|
||||
"name": "x-y",
|
||||
"url": "http://pokeapi.co/api/v2/version-group/15/"
|
||||
"name": "red-blue",
|
||||
"url": "https://pokeapi.co/api/v2/version-group/1/"
|
||||
},
|
||||
"move_learn_method": {
|
||||
"name": "machine",
|
||||
"url": "http://pokeapi.co/api/v2/move-learn-method/4/"
|
||||
"name": "level-up",
|
||||
"url": "https://pokeapi.co/api/v2/move-learn-method/1/"
|
||||
}
|
||||
}]
|
||||
}],
|
||||
"species": {
|
||||
"name": "butterfree",
|
||||
"url": "http://pokeapi.co/api/v2/pokemon-species/12/"
|
||||
"name": "clefairy",
|
||||
"url": "https://pokeapi.co/api/v2/pokemon-species/35/"
|
||||
},
|
||||
"stats": [{
|
||||
"base_stat": 70,
|
||||
"base_stat": 35,
|
||||
"effort": 0,
|
||||
"stat": {
|
||||
"name": "speed",
|
||||
"url": "http://pokeapi.co/api/v2/stat/6/"
|
||||
"url": "https://pokeapi.co/api/v2/stat/6/"
|
||||
}
|
||||
}],
|
||||
"types": [{
|
||||
"slot": 2,
|
||||
"slot": 1,
|
||||
"type": {
|
||||
"name": "flying",
|
||||
"url": "http://pokeapi.co/api/v2/type/3/"
|
||||
"name": "fairy",
|
||||
"url": "https://pokeapi.co/api/v2/type/18/"
|
||||
}
|
||||
}],
|
||||
"past_types": [{
|
||||
"generation": {
|
||||
"name": "generation-v",
|
||||
"url": "https://pokeapi.co/api/v2/generation/5/"
|
||||
},
|
||||
"types": [
|
||||
{
|
||||
"slot": 1,
|
||||
"type": {
|
||||
"name": "normal",
|
||||
"url": "https://pokeapi.co/api/v2/type/1/"
|
||||
}
|
||||
}
|
||||
]
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
@ -2392,6 +2382,7 @@ Pokémon are the creatures that inhabit the world of the pokemon games. They can
|
|||
| species | The species this pokémon belongs to | [NamedAPIResource](#namedapiresource) ([PokemonSpecies](#pokemon-species)) |
|
||||
| stats | A list of base stat values for this pokémon | list [NamedAPIResource](#namedapiresource) ([Stat](#stats)) |
|
||||
| types | A list of details showing types this pokémon has | list [PokemonType](#pokemontype) |
|
||||
| past_types | A list of details showing types this pokémon had in previous generations | list [PokemonTypePast](#pokemontypepast) |
|
||||
|
||||
#### PokemonAbility
|
||||
|
||||
|
@ -2408,6 +2399,13 @@ Pokémon are the creatures that inhabit the world of the pokemon games. They can
|
|||
| slot | The order the pokémon types are listed in | integer |
|
||||
| type | The type the referenced pokémon has | string |
|
||||
|
||||
#### PokemonTypePast
|
||||
|
||||
| Name | Description | Data Type |
|
||||
| ---- | ----------- | --------- |
|
||||
| generation | The last generation in which the referenced pokémon had the listed types | [NamedAPIResource](#namedapiresource) ([Generation](#generations)) |
|
||||
| types | The types the referenced pokémon had up to and including the listed generation | list [PokemonType](#pokemontype) |
|
||||
|
||||
#### LocationAreaEncounter
|
||||
|
||||
| Name | Description | Data Type |
|
||||
|
|
62
pokemon_v2/migrations/0009_pokemontypepast.py
Normal file
62
pokemon_v2/migrations/0009_pokemontypepast.py
Normal file
|
@ -0,0 +1,62 @@
|
|||
# Generated by Django 2.1.11 on 2021-02-06 22:03
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("pokemon_v2", "0008_auto_20201123_2045"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="PokemonTypePast",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("slot", models.IntegerField()),
|
||||
(
|
||||
"generation",
|
||||
models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="pokemontypepast",
|
||||
to="pokemon_v2.Generation",
|
||||
),
|
||||
),
|
||||
(
|
||||
"pokemon",
|
||||
models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="pokemontypepast",
|
||||
to="pokemon_v2.Pokemon",
|
||||
),
|
||||
),
|
||||
(
|
||||
"type",
|
||||
models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="pokemontypepast",
|
||||
to="pokemon_v2.Type",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"abstract": False,
|
||||
},
|
||||
),
|
||||
]
|
|
@ -1872,6 +1872,12 @@ class PokemonType(HasPokemon, HasType):
|
|||
slot = models.IntegerField()
|
||||
|
||||
|
||||
# model for a Pokemon's types that were used until a given generation
|
||||
class PokemonTypePast(HasPokemon, HasType, HasGeneration):
|
||||
|
||||
slot = models.IntegerField()
|
||||
|
||||
|
||||
class PokemonSprites(HasPokemon):
|
||||
|
||||
sprites = models.CharField(max_length=20000)
|
||||
|
|
|
@ -386,6 +386,16 @@ class PokemonTypeSerializer(serializers.ModelSerializer):
|
|||
fields = ("slot", "pokemon", "type")
|
||||
|
||||
|
||||
class PokemonTypePastSerializer(serializers.ModelSerializer):
|
||||
|
||||
generation = GenerationSummarySerializer()
|
||||
type = TypeSummarySerializer()
|
||||
|
||||
class Meta:
|
||||
model = PokemonTypePast
|
||||
fields = ("pokemon", "generation", "slot", "type")
|
||||
|
||||
|
||||
class PokedexVersionGroupSerializer(serializers.ModelSerializer):
|
||||
|
||||
pokedex = PokedexSummarySerializer()
|
||||
|
@ -2721,6 +2731,7 @@ class PokemonDetailSerializer(serializers.ModelSerializer):
|
|||
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"
|
||||
)
|
||||
|
@ -2748,6 +2759,7 @@ class PokemonDetailSerializer(serializers.ModelSerializer):
|
|||
"sprites",
|
||||
"stats",
|
||||
"types",
|
||||
"past_types",
|
||||
)
|
||||
|
||||
def get_pokemon_sprites(self, obj):
|
||||
|
@ -2887,6 +2899,42 @@ class PokemonDetailSerializer(serializers.ModelSerializer):
|
|||
|
||||
return poke_types
|
||||
|
||||
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
|
||||
|
||||
def get_encounters(self, obj):
|
||||
|
||||
return reverse("pokemon_encounters", kwargs={"pokemon_id": obj.pk})
|
||||
|
|
|
@ -1710,6 +1710,18 @@ class APIData:
|
|||
|
||||
return pokemon_type
|
||||
|
||||
@classmethod
|
||||
def setup_pokemon_past_type_data(cls, pokemon, generation, type=None, slot=1):
|
||||
|
||||
type = type or cls.setup_type_data(name="tp for pkmn")
|
||||
|
||||
pokemon_type_past = PokemonTypePast(
|
||||
pokemon=pokemon, generation=generation, type=type, slot=slot
|
||||
)
|
||||
pokemon_type_past.save()
|
||||
|
||||
return pokemon_type_past
|
||||
|
||||
@classmethod
|
||||
def setup_pokemon_item_data(cls, pokemon=None, item=None, version=None, rarity=50):
|
||||
|
||||
|
@ -4804,6 +4816,10 @@ class APITests(APIData, APITestCase):
|
|||
pokemon_ability = self.setup_pokemon_ability_data(pokemon=pokemon)
|
||||
pokemon_stat = self.setup_pokemon_stat_data(pokemon=pokemon)
|
||||
pokemon_type = self.setup_pokemon_type_data(pokemon=pokemon)
|
||||
generation = self.setup_generation_data(name="base gen")
|
||||
pokemon_past_type = self.setup_pokemon_past_type_data(
|
||||
pokemon=pokemon, generation=generation
|
||||
)
|
||||
pokemon_item = self.setup_pokemon_item_data(pokemon=pokemon)
|
||||
pokemon_sprites = self.setup_pokemon_sprites_data(pokemon=pokemon)
|
||||
pokemon_game_index = self.setup_pokemon_game_index_data(
|
||||
|
@ -4896,7 +4912,7 @@ class APITests(APIData, APITestCase):
|
|||
response.data["stats"][0]["stat"]["url"],
|
||||
"{}{}/stat/{}/".format(TEST_HOST, API_V2, pokemon_stat.stat.pk),
|
||||
)
|
||||
# stat params
|
||||
# type params
|
||||
self.assertEqual(response.data["types"][0]["slot"], pokemon_type.slot)
|
||||
self.assertEqual(
|
||||
response.data["types"][0]["type"]["name"], pokemon_type.type.name
|
||||
|
@ -4905,6 +4921,28 @@ class APITests(APIData, APITestCase):
|
|||
response.data["types"][0]["type"]["url"],
|
||||
"{}{}/type/{}/".format(TEST_HOST, API_V2, pokemon_type.type.pk),
|
||||
)
|
||||
# past type params
|
||||
past_types_obj = response.data["past_types"][0]
|
||||
self.assertEqual(
|
||||
past_types_obj["generation"]["name"], pokemon_past_type.generation.name
|
||||
)
|
||||
self.assertEqual(
|
||||
past_types_obj["generation"]["url"],
|
||||
"{}{}/generation/{}/".format(
|
||||
TEST_HOST, API_V2, pokemon_past_type.generation.pk
|
||||
),
|
||||
)
|
||||
|
||||
past_types_types_obj = past_types_obj["types"][0]
|
||||
self.assertEqual(past_types_types_obj["slot"], pokemon_past_type.slot)
|
||||
self.assertEqual(
|
||||
past_types_types_obj["type"]["name"], pokemon_past_type.type.name
|
||||
)
|
||||
self.assertEqual(
|
||||
past_types_types_obj["type"]["url"],
|
||||
"{}{}/type/{}/".format(TEST_HOST, API_V2, pokemon_past_type.type.pk),
|
||||
)
|
||||
|
||||
# items params
|
||||
self.assertEqual(
|
||||
response.data["held_items"][0]["item"]["name"], pokemon_item.item.name
|
||||
|
|
Loading…
Reference in a new issue