Merge pull request #457 from phrasmotica/past-pokemon-types

This commit is contained in:
Alessandro Pezzè 2021-02-12 21:47:21 +01:00 committed by GitHub
commit e2e43d8bda
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 258 additions and 59 deletions

View file

@ -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 #

View 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
1 pokemon_id generation_id type_id slot
2 35 5 1 1
3 36 5 1 1
4 39 5 1 1
5 40 5 1 1
6 81 1 13 1
7 82 1 13 1
8 122 5 14 1
9 173 5 1 1
10 174 5 1 1
11 175 5 1 1
12 176 5 1 1
13 176 5 3 2
14 183 5 11 1
15 184 5 11 1
16 209 5 1 1
17 210 5 1 1
18 280 5 14 1
19 281 5 14 1
20 282 5 14 1
21 298 5 1 1
22 303 5 9 1
23 439 5 14 1
24 468 5 1 1
25 468 5 3 2
26 546 5 12 1
27 547 5 12 1
28 10008 4 13 1
29 10008 4 8 2
30 10009 4 13 1
31 10009 4 8 2
32 10010 4 13 1
33 10010 4 8 2
34 10011 4 13 1
35 10011 4 8 2
36 10012 4 13 1
37 10012 4 8 2

View file

@ -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 |

View 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,
},
),
]

View file

@ -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)

View file

@ -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})

View file

@ -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