Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions pokemon_v2/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,11 @@ class PokemonResource(PokeapiCommonViewset):
serializer_class = PokemonDetailSerializer
list_serializer_class = PokemonSummarySerializer

def get_queryset(self):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very interesting implementation. Can I ask what's the purpose of this function? It's for having ready at hand some data later on in the serializer.py part?

if self.action == "retrieve":
return Pokemon.objects.all().select_related("pokemon_species")
return super().get_queryset()


@extend_schema(
description="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.",
Expand Down
29 changes: 28 additions & 1 deletion pokemon_v2/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4418,7 +4418,34 @@ class Meta:
)
def get_pokemon_sprites(self, obj):
sprites_object = PokemonSprites.objects.get(pokemon_id=obj)
return sprites_object.sprites
sprites = sprites_object.sprites
if obj.pokemon_species.gender_rate == 8:
if isinstance(sprites, str):
parsed = json.loads(sprites)
self._fill_female_sprites(parsed)
return json.dumps(parsed)
self._fill_female_sprites(sprites)
return sprites

_FEMALE_FALLBACKS = {
"front_female": "front_default",
"back_female": "back_default",
"front_shiny_female": "front_shiny",
"back_shiny_female": "back_shiny",
}

def _fill_female_sprites(self, node):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm strongly of the opinion that the data should just be shared with PokeAPI and consumers should handle this themselves.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Among the years we always pulled data from veekun which in turn got it from decompilations. The data was sometimes pretty cryptic to use. I can mention the use of rare Unicode characters, having braces in strings that acted as templates, having hidden characters and so on. In the beginning we were reluctant to change these pieces of data turning to the users to implement custom strategies.

Eventually we cleaned the garbage that we were serving and everyone was happier. Maybe valuing user-friendliness over strict data rules was the key to it.

That said I'm in favour of these kind of changes. If a pokemon has a 100% female rate then the female_sprite can be inferred to be the same as the default_sprite. In this case default_sprite and female_sprite coincide. By having the female_sprite filled in (by this custom logic or any other method) is ok with me.

if not isinstance(node, dict):
return
for female_key, default_key in self._FEMALE_FALLBACKS.items():
if (
female_key in node
and node[female_key] is None
and node.get(default_key) is not None
):
node[female_key] = node[default_key]
for value in node.values():
self._fill_female_sprites(value)

@extend_schema_field(
field={
Expand Down
30 changes: 30 additions & 0 deletions pokemon_v2/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -5257,6 +5257,36 @@ def test_pokemon_api(self):
self.assertEqual(response.data["count"], 1)
self.assertEqual(response.data["results"][0]["name"], pokemon.name)

def test_pokemon_api_female_only_sprites_fallback(self):
pokemon_species = self.setup_pokemon_species_data(
name="female only pkmn spcs", gender_rate=8
)
pokemon = self.setup_pokemon_data(
pokemon_species=pokemon_species, name="female only pkmn"
)
self.setup_pokemon_form_data(pokemon=pokemon, name="female only pkmn form")
pokemon_sprites = self.setup_pokemon_sprites_data(
pokemon=pokemon, front_default=True, front_female=False
)
self.setup_pokemon_cries_data(pokemon, latest=True, legacy=True)

response = self.client.get(
"{}/pokemon/{}/".format(API_V2, pokemon.pk), headers={"host": "testserver"}
)
self.assertEqual(response.status_code, status.HTTP_200_OK)

sprites_data = json.loads(pokemon_sprites.sprites)
response_sprites = json.loads(response.data["sprites"])

self.assertIsNotNone(response_sprites["front_default"])
self.assertEqual(
response_sprites["front_female"], response_sprites["front_default"]
)
self.assertEqual(
response_sprites["other"]["showdown"]["front_female"],
response_sprites["other"]["showdown"]["front_default"],
)

def test_pokemon_form_api(self):
pokemon_species = self.setup_pokemon_species_data()
pokemon = self.setup_pokemon_data(pokemon_species=pokemon_species)
Expand Down
Loading