mirror of
https://github.com/PokeAPI/pokeapi
synced 2024-11-25 21:00:19 +00:00
Merge pull request #571 from phrasmotica/feature/pokemon-form-types
This commit is contained in:
commit
a33d08539d
7 changed files with 206 additions and 34 deletions
|
@ -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])
|
||||
|
|
36
data/v2/csv/pokemon_form_types.csv
Normal file
36
data/v2/csv/pokemon_form_types.csv
Normal 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
|
|
|
@ -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 |
|
||||
|
|
52
pokemon_v2/migrations/0010_pokemonformtype.py
Normal file
52
pokemon_v2/migrations/0010_pokemonformtype.py
Normal 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
5
pokemon_v2/models.py
Executable file → Normal 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):
|
||||
|
||||
|
|
|
@ -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 #
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Reference in a new issue