Merge pull request #571 from phrasmotica/feature/pokemon-form-types

This commit is contained in:
Alessandro Pezzè 2021-02-23 18:21:40 +01:00 committed by GitHub
commit a33d08539d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 206 additions and 34 deletions

View file

@ -1964,6 +1964,13 @@ def _build_pokemons():
(PokemonFormGeneration,), "pokemon_form_generations.csv", csv_record_to_objects
)
def csv_record_to_objects(info):
yield PokemonFormType(
pokemon_form_id=int(info[0]), type_id=int(info[1]), slot=int(info[2])
)
build_generic((PokemonFormType,), "pokemon_form_types.csv", csv_record_to_objects)
def csv_record_to_objects(info):
yield PokemonGameIndex(
pokemon_id=int(info[0]), version_id=int(info[1]), game_index=int(info[2])

View file

@ -0,0 +1,36 @@
pokemon_form_id,type_id,slot
10041,7,1
10042,17,1
10043,16,1
10044,13,1
10045,2,1
10046,10,1
10047,3,1
10048,8,1
10049,12,1
10050,5,1
10051,15,1
10052,4,1
10053,14,1
10054,6,1
10055,9,1
10056,11,1
10057,10001,1
10085,18,1
10232,2,1
10233,3,1
10234,4,1
10235,5,1
10236,6,1
10237,7,1
10238,8,1
10239,9,1
10240,10,1
10241,11,1
10242,12,1
10243,13,1
10244,14,1
10245,15,1
10246,16,1
10247,17,1
10248,18,1
1 pokemon_form_id type_id slot
2 10041 7 1
3 10042 17 1
4 10043 16 1
5 10044 13 1
6 10045 2 1
7 10046 10 1
8 10047 3 1
9 10048 8 1
10 10049 12 1
11 10050 5 1
12 10051 15 1
13 10052 4 1
14 10053 14 1
15 10054 6 1
16 10055 9 1
17 10056 11 1
18 10057 10001 1
19 10085 18 1
20 10232 2 1
21 10233 3 1
22 10234 4 1
23 10235 5 1
24 10236 6 1
25 10237 7 1
26 10238 8 1
27 10239 9 1
28 10240 10 1
29 10241 11 1
30 10242 12 1
31 10243 13 1
32 10244 14 1
33 10245 15 1
34 10246 16 1
35 10247 17 1
36 10248 18 1

View file

@ -398,7 +398,7 @@ Super contest effects refer to the effects of moves when used in super contests.
#### SuperContestEffect
| Name | Description | Data Type |
| Name | Description | Data Type |
| ---- | ----------- | --------- |
| id | The identifier for this super contest effect resource | integer |
| appeal | The level of appeal this super contest effect has | string |
@ -795,7 +795,7 @@ A Pokédex is a handheld electronic encyclopedia device; one which is capable of
## Versions
Versions of the games, e.g., Red, Blue or Yellow.
Versions of the games, e.g., Red, Blue or Yellow.
### GET api/v2/version/{id or name}
@ -833,7 +833,7 @@ Versions of the games, e.g., Red, Blue or Yellow.
## Version Groups
Version groups categorize highly similar versions of the games.
Version groups categorize highly similar versions of the games.
### GET api/v2/version-group/{id or name}
@ -1114,7 +1114,7 @@ The various effects of the move "Fling" when used with different items.
| Name | Description | Data Type |
| ---- | ----------- | --------- |
| id | The identifier for this fling effect resource | integer |
| id | The identifier for this fling effect resource | integer |
| name | The name for this fling effect resource | string |
| effect_entries | The result of this fling effect listed in different languages | list [Effect](#effect) |
| items | A list of items that have this fling effect | list [NamedAPIResource](#namedapiresource) ([Item](#items)) |
@ -1290,7 +1290,7 @@ Moves are the skills of pokémon in battle. In battle, a Pokémon uses one move
| type | The elemental type of this move | [NamedAPIResource](#namedapiresource) ([Type](#types)) |
#### ContestComboSets
| Name | Description | Data Type |
| ---- | ----------- | --------- |
| normal | A detail of moves this move can be used before or after, granting additional appeal points in contests | list [ContestComboDetail](#contestcombodetail) |
@ -1300,7 +1300,7 @@ Moves are the skills of pokémon in battle. In battle, a Pokémon uses one move
| Name | Description | Data Type |
| ---- | ----------- | --------- |
| use_before | A list of moves to use before this move | list [NamedAPIResource](#namedapiresource) ([Move](#moves)) |
| use_before | A list of moves to use before this move | list [NamedAPIResource](#namedapiresource) ([Move](#moves)) |
| use_after | A list of moves to use after this move | list [NamedAPIResource](#namedapiresource) ([Move](#moves)) |
#### MoveMetaData
@ -1918,7 +1918,7 @@ Abilities provide passive effects for pokémon in battle or in the overworld. Po
| effect_entries | The previous effect of this ability listed in different languages | [Effect](#effect) |
| version_group | The version group in which the previous effect of this ability originated | [NamedAPIResource](#namedapiresource) ([VersionGroup](#versiongroups)) |
#### AbilityFlavorText
#### AbilityFlavorText
| Name | Description | Data Type |
| ---- | ----------- | --------- |
@ -2013,7 +2013,7 @@ Egg Groups are categories which determine which Pokémon are able to interbreed.
## Genders
Genders were introduced in Generation II for the purposes of breeding pokémon but can also result in visual differences or even different evolutionary lines. Check out [Bulbapedia](http://bulbapedia.bulbagarden.net/wiki/Gender) for greater detail.
Genders were introduced in Generation II for the purposes of breeding pokémon but can also result in visual differences or even different evolutionary lines. Check out [Bulbapedia](http://bulbapedia.bulbagarden.net/wiki/Gender) for greater detail.
### GET api/v2/gender/{id or name}
@ -2059,7 +2059,7 @@ Genders were introduced in Generation II for the purposes of breeding pokémon b
## Growth Rates
Growth rates are the speed with which pokémon gain levels through experience. Check out [Bulbapedia](http://bulbapedia.bulbagarden.net/wiki/Experience) for greater detail.
Growth rates are the speed with which pokémon gain levels through experience. Check out [Bulbapedia](http://bulbapedia.bulbagarden.net/wiki/Experience) for greater detail.
### GET api/v2/growth-rate/{id or name}
@ -2169,7 +2169,7 @@ Natures influence how a pokémon's stats grow. See [Bulbapedia](http://bulbapedi
| ---- | ----------- | --------- |
| id | The identifier for this nature resource | integer |
| name | The name for this nature resource | string |
| decreased_stat | The stat decreased by 10% in pokémon with this nature | [NamedAPIResource](#namedapiresource) ([Stat](#stats)) |
| decreased_stat | The stat decreased by 10% in pokémon with this nature | [NamedAPIResource](#namedapiresource) ([Stat](#stats)) |
| increased_stat | The stat increased by 10% in pokémon with this nature | [NamedAPIResource](#namedapiresource) ([Stat](#stats)) |
| hates_flavor | The flavor hated by pokémon with this nature | [NamedAPIResource](#namedapiresource) ([BerryFlavor](#berry-flavors)) |
| likes_flavor | The flavor liked by pokémon with this nature | [NamedAPIResource](#namedapiresource) ([BerryFlavor](#berry-flavors)) |
@ -2380,7 +2380,7 @@ Pokémon are the creatures that inhabit the world of the pokemon games. They can
| location_area_encounters | A list of location areas as well as encounter details pertaining to specific versions | list [LocationAreaEncounter](#locationareaencounter) |
| moves | A list of moves along with learn methods and level details pertaining to specific version groups | list [NamedAPIResource](#namedapiresource) ([Move](#moves)) |
| 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)) |
| 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) |
@ -2399,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 |
#### PokemonFormType
| Name | Description | Data Type |
| ---- | ----------- | --------- |
| slot | The order the Pokémon form types are listed in | integer |
| type | The type the referenced Pokémon form has | string |
#### PokemonTypePast
| Name | Description | Data Type |
@ -2460,22 +2467,31 @@ Some pokémon have the ability to take on different forms. At times, these diffe
```json
{
"id": 413,
"name": "wormadam-plant",
"order": 503,
"form_order": 1,
"is_default": true,
"is_battle_only": false,
"is_mega": false,
"form_name": "plant",
"pokemon": {
"name": "wormadam-plant",
"url": "http://pokeapi.co/api/v2/pokemon/413/"
},
"version_group": {
"name": "diamond-pearl",
"url": "http://pokeapi.co/api/v2/version-group/8/"
}
"id": 10041,
"name": "arceus-bug",
"order": 631,
"form_order": 7,
"is_default": false,
"is_battle_only": false,
"is_mega": false,
"form_name": "bug",
"pokemon": {
"name": "arceus",
"url": "https://pokeapi.co/api/v2/pokemon/493/"
},
"version_group": {
"name": "diamond-pearl",
"url": "https://pokeapi.co/api/v2/version-group/8/"
},
"types": [
{
"slot": 1,
"type": {
"name": "bug",
"url": "https://pokeapi.co/api/v2/type/7/"
}
}
]
}
```
@ -2495,6 +2511,7 @@ Some pokémon have the ability to take on different forms. At times, these diffe
| form_name | The name of this form | string |
| pokemon | The pokémon that can take on this form | [NamedAPIResource](#namedapiresource) ([Pokemon](#pokemon)) |
| version_group | The version group this pokémon form was introduced in | [NamedAPIResource](#namedapiresource) ([VersionGroup](#version-groups)) |
| types | A list of details showing types this Pokémon form has, if they differ from the types of the Pokémon that can take on this form | list [PokemonFormType](#pokemonformtype) |
## Pokémon Habitats
@ -2539,7 +2556,7 @@ Habitats are generally different terrain pokémon can be found in but can also b
## Pokémon Shapes
Shapes used for sorting pokémon in a pokédex.
Shapes used for sorting pokémon in a pokédex.
### GET api/v2/pokemon-shape/{id or name}
@ -2597,7 +2614,7 @@ Shapes used for sorting pokémon in a pokédex.
## Pokémon Species
A Pokémon Species forms the basis for at least one pokémon. Attributes of a Pokémon species are shared across all varieties of pokémon within the species. A good example is Wormadam; Wormadam is the species which can be found in three different varieties, Wormadam-Trash, Wormadam-Sandy and Wormadam-Plant.
A Pokémon Species forms the basis for at least one pokémon. Attributes of a Pokémon species are shared across all varieties of pokémon within the species. A good example is Wormadam; Wormadam is the species which can be found in three different varieties, Wormadam-Trash, Wormadam-Sandy and Wormadam-Plant.
### GET api/v2/pokemon-species/{id or name}
@ -2685,9 +2702,9 @@ A Pokémon Species forms the basis for at least one pokémon. Attributes of a Po
#### PokemonSpecies
| Name | Description | Data Type |
| Name | Description | Data Type |
| ---- | ----------- | --------- |
| id | The identifier for this pokémon species resource | integer |
| id | The identifier for this pokémon species resource | integer |
| name | The name for this pokémon species resource | string |
| order | The order in which species should be sorted. Based on National Dex order, except families are grouped together and sorted by stage. | integer |
| gender_rate | The chance of this Pokémon being female, in eighths; or -1 for genderless | integer |
@ -2936,7 +2953,7 @@ Types are properties for Pokémon and their moves. Each type has three propertie
#### TypeRelations
| Name | Description | Data Type |
| Name | Description | Data Type |
| ---- | ----------- | --------- |
| no_damage_to | A list of types this type has no effect on | list [NamedAPIResource](#namedapiresource) ([Type](#types)) |
| half_damage_to | A list of types this type is not very effect against | list [NamedAPIResource](#namedapiresource) ([Type](#types)) |
@ -2998,7 +3015,7 @@ Languages for translations of api resource information.
#### Description
| Name | Description | Data Type |
| Name | Description | Data Type |
| ---- | ----------- | --------- |
| description | The localized description for an api resource in a specific language | string |
| language | The language this description is in | [NamedAPIResource](#namedapiresource) ([Language](#languages)) |
@ -3048,7 +3065,7 @@ Languages for translations of api resource information.
#### NamedAPIResource
| Name | Description | Data Type |
| Name | Description | Data Type |
| ---- | ----------- | --------- |
| name | The name of the referenced resource | string |
| url | The url of the referenced resource | string |

View file

@ -0,0 +1,52 @@
# Generated by Django 2.1.11 on 2021-02-18 20:45
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("pokemon_v2", "0009_pokemontypepast"),
]
operations = [
migrations.CreateModel(
name="PokemonFormType",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("slot", models.IntegerField()),
(
"pokemon_form",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="pokemonformtype",
to="pokemon_v2.PokemonForm",
),
),
(
"type",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="pokemonformtype",
to="pokemon_v2.Type",
),
),
],
options={
"abstract": False,
},
),
]

5
pokemon_v2/models.py Executable file → Normal file
View file

@ -1872,6 +1872,11 @@ class PokemonType(HasPokemon, HasType):
slot = models.IntegerField()
class PokemonFormType(HasPokemonForm, HasType):
slot = models.IntegerField()
# model for a Pokemon's types that were used until a given generation
class PokemonTypePast(HasPokemon, HasType, HasGeneration):

View file

@ -386,6 +386,16 @@ class PokemonTypeSerializer(serializers.ModelSerializer):
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()
@ -2466,6 +2476,7 @@ class PokemonFormDetailSerializer(serializers.ModelSerializer):
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
@ -2483,6 +2494,7 @@ class PokemonFormDetailSerializer(serializers.ModelSerializer):
"version_group",
"form_names",
"names",
"types",
)
def get_pokemon_form_names(self, obj):
@ -2536,6 +2548,29 @@ class PokemonFormDetailSerializer(serializers.ModelSerializer):
return sprites_data
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 #

View file

@ -1646,6 +1646,16 @@ class APIData:
return pokemon_form_sprites
@classmethod
def setup_pokemon_form_type_data(cls, pokemon_form, type=None, slot=1):
type = type or cls.setup_type_data(name="tp for pkmn frm")
form_type = PokemonFormType(pokemon_form=pokemon_form, type=type, slot=slot)
form_type.save()
return form_type
@classmethod
def setup_pokemon_form_data(
cls,
@ -5045,6 +5055,7 @@ class APITests(APIData, APITestCase):
pokemon=pokemon, name="pkm form for base pkmn"
)
pokemon_form_sprites = self.setup_pokemon_form_sprites_data(pokemon_form)
pokemon_form_type = self.setup_pokemon_form_type_data(pokemon_form)
sprites_data = json.loads(pokemon_form_sprites.sprites)
@ -5088,6 +5099,15 @@ class APITests(APIData, APITestCase):
),
)
self.assertEqual(response.data["sprites"]["back_default"], None)
# type params
self.assertEqual(response.data["types"][0]["slot"], pokemon_form_type.slot)
self.assertEqual(
response.data["types"][0]["type"]["name"], pokemon_form_type.type.name
)
self.assertEqual(
response.data["types"][0]["type"]["url"],
"{}{}/type/{}/".format(TEST_HOST, API_V2, pokemon_form_type.type.pk),
)
# Evolution test
def test_evolution_trigger_api(self):