Create serialiser for past type efficacy

This commit is contained in:
Julian Lawrance 2019-12-01 12:41:28 +00:00
parent e847276e9b
commit 2524b48c56

View file

@ -1667,6 +1667,15 @@ class TypeEfficacySerializer(serializers.ModelSerializer):
fields = '__all__'
class TypeEfficacyPastSerializer(serializers.ModelSerializer):
generation = GenerationSummarySerializer()
class Meta:
model = TypeEfficacyPast
fields = ('target_type', 'damage_type', 'damage_factor', 'generation')
class TypeGameIndexSerializer(serializers.ModelSerializer):
generation = GenerationSummarySerializer()
@ -1694,16 +1703,30 @@ class TypeDetailSerializer(serializers.ModelSerializer):
game_indices = TypeGameIndexSerializer(many=True, read_only=True, source="typegameindex")
move_damage_class = MoveDamageClassSummarySerializer()
damage_relations = serializers.SerializerMethodField('get_type_relationships')
past_damage_relations = serializers.SerializerMethodField('get_type_past_relationships')
pokemon = serializers.SerializerMethodField('get_type_pokemon')
moves = MoveSummarySerializer(many=True, read_only=True, source="move")
class Meta:
model = Type
fields = (
'id', 'name', 'damage_relations', 'game_indices', 'generation',
'id', 'name', 'damage_relations', 'past_damage_relations', 'game_indices', 'generation',
'move_damage_class', 'names', 'pokemon', 'moves'
)
# adds an entry for the given type with the given damage
# factor in the given direction to the set of relations
def add_type_entry(self, relations, type, damage_factor, direction='_damage_to'):
if damage_factor == 200:
relations['double' + direction].append(
TypeSummarySerializer(type, context=self.context).data)
elif damage_factor == 50:
relations['half' + direction].append(
TypeSummarySerializer(type, context=self.context).data)
elif damage_factor == 0:
relations['no' + direction].append(
TypeSummarySerializer(type, context=self.context).data)
def get_type_relationships(self, obj):
relations = OrderedDict()
@ -1749,6 +1772,103 @@ class TypeDetailSerializer(serializers.ModelSerializer):
return relations
# takes a list of past type relations by generation and
# returns a list of lists where each list has the entries
# for a single generation
def group_relations_by_generation(self, serializer_data):
data_by_gen = []
current_generation = ""
generation_data = []
for relation in serializer_data:
gen_name = relation['generation']['name']
if gen_name != current_generation:
# first item for this generation so create its list
current_generation = gen_name
generation_data = [relation]
data_by_gen.append(generation_data)
else:
# add to this generation's list
generation_data.append(relation)
return data_by_gen
# removes the entry for the given type in
# the given direction from the set of relations
def remove_type_entry(self, relations, type, direction='_damage_to'):
for k in ['double', 'half', 'no']:
rel_list = relations[k + direction]
for i, o in enumerate(rel_list):
if o['name'] == type.name:
del rel_list[i]
return
# returns past type relationships for the given type object
def get_type_past_relationships(self, obj):
# collect data from DB
damage_type_results = TypeEfficacyPast.objects.filter(damage_type=obj)
target_type_results = TypeEfficacyPast.objects.filter(target_type=obj)
serializer = TypeEfficacyPastSerializer(
damage_type_results + target_type_results,
many=True,
context=self.context
)
# group data by generation
data_by_gen = self.group_relations_by_generation(serializer.data)
# process each generation's data in turn
final_data = []
past_relations = {}
for gen_data in data_by_gen:
# create past relations object for this generation
past_relations = OrderedDict()
# set generation
past_relations['generation'] = gen_data[0]['generation']
# use current damage relations object
past_relations['damage_relations'] = self.get_type_relationships(obj)
relations = past_relations['damage_relations']
# populate offensive relations
results = list(filter(lambda x: x['damage_type'] == obj.id, gen_data))
for relation in results:
type = Type.objects.get(pk=relation['target_type'])
# remove conflicting entry if it exists
self.remove_type_entry(relations, type, direction='_damage_to')
# add entry
damage_factor = relations['damage_factor']
self.add_type_entry(relations, type, damage_factor, direction='_damage_to')
del relation['generation']
# populate defensive relations
results = list(filter(lambda x: x['target_type'] == obj.id, gen_data))
for relation in results:
type = Type.objects.get(pk=relation['damage_type'])
# remove conflicting entry if it exists
self.remove_type_entry(relations, type, direction='_damage_from')
# add entry
damage_factor = relation['damage_factor']
self.add_type_entry(relations, type, damage_factor, direction='_damage_from')
del relation['generation']
# add to final list
final_data.append(past_relations)
return final_data
def get_type_pokemon(self, obj):
poke_type_objects = PokemonType.objects.filter(type=obj)