mirror of
https://github.com/PokeAPI/pokeapi
synced 2025-02-16 12:38:25 +00:00
Optimisations (#174)
* removed all the things causing slow times on data * fixup look sharp * use ujson * bep
This commit is contained in:
parent
5b94cff6c8
commit
422d98fff2
7 changed files with 16 additions and 244 deletions
|
@ -95,6 +95,7 @@ DATABASES = {
|
|||
'PASSWORD': 'pokeapi',
|
||||
'HOST': 'localhost',
|
||||
'PORT': '',
|
||||
'CONN_MAX_AGE': 30
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,10 +104,6 @@ CACHES = {
|
|||
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
|
||||
'TIMEOUT': 30
|
||||
},
|
||||
'resources': {
|
||||
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
|
||||
'TIMEOUT': 360
|
||||
}
|
||||
}
|
||||
|
||||
SECRET_KEY = os.environ.get(
|
||||
|
@ -148,10 +145,10 @@ CORS_URLS_REGEX = r'^/api/.*$'
|
|||
|
||||
REST_FRAMEWORK = {
|
||||
'DEFAULT_RENDERER_CLASSES': (
|
||||
'rest_framework.renderers.JSONRenderer',
|
||||
'drf_ujson.renderers.UJSONRenderer',
|
||||
),
|
||||
'DEFAULT_PARSER_CLASSES': (
|
||||
'rest_framework.parsers.JSONParser',
|
||||
'drf_ujson.renderers.UJSONRenderer',
|
||||
),
|
||||
|
||||
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
|
||||
|
|
217
config/views.py
217
config/views.py
|
@ -10,224 +10,10 @@ from hits.models import ResourceView
|
|||
|
||||
import stripe
|
||||
|
||||
from pokemon_v2.models import * # NOQA
|
||||
|
||||
|
||||
def _total_site_data():
|
||||
|
||||
"""
|
||||
Compute the total count of objects on the site
|
||||
|
||||
Using count() is drastically cheaper than len(objects.all())
|
||||
"""
|
||||
|
||||
# v2 Sorry for the brute force. Theres probably a better way to do this.
|
||||
data = dict(
|
||||
abilities=Ability.objects.count(),
|
||||
abilitie_names=AbilityName.objects.count(),
|
||||
abilitie_effect_texts=AbilityEffectText.objects.count(),
|
||||
abilities_flavor_texts=AbilityFlavorText.objects.count(),
|
||||
abilities_changes=AbilityChange.objects.count(),
|
||||
abilities_change_effect_texts=AbilityChangeEffectText.objects.count(),
|
||||
berries=Berry.objects.count(),
|
||||
berry_flavors=BerryFlavor.objects.count(),
|
||||
berry_firmnesses=BerryFirmness.objects.count(),
|
||||
berry_firmness_names=BerryFirmnessName.objects.count(),
|
||||
characteristics=Characteristic.objects.count(),
|
||||
characteristic_descriptions=CharacteristicDescription.objects.count(),
|
||||
contest_combos=ContestCombo.objects.count(),
|
||||
contest_types=ContestType.objects.count(),
|
||||
contest_type_names=ContestTypeName.objects.count(),
|
||||
contest_effects=ContestEffect.objects.count(),
|
||||
contest_effect_texts=ContestEffectEffectText.objects.count(),
|
||||
contest_effect_flavor_texts=ContestEffectFlavorText.objects.count(),
|
||||
egg_groups=EggGroup.objects.count(),
|
||||
egg_group_names=EggGroupName.objects.count(),
|
||||
encounter_methods=EncounterMethod.objects.count(),
|
||||
encounter_method_names=EncounterMethodName.objects.count(),
|
||||
encounter_conditions=EncounterCondition.objects.count(),
|
||||
encounter_condition_names=EncounterConditionName.objects.count(),
|
||||
encounter_condition_values=EncounterConditionValue.objects.count(),
|
||||
encounter_condition_value_names=EncounterConditionValueName.objects.count(),
|
||||
encounter_condition_value_maps=EncounterConditionValueMap.objects.count(),
|
||||
encounter_slots=EncounterSlot.objects.count(),
|
||||
encounters=Encounter.objects.count(),
|
||||
evolution_chains=EvolutionChain.objects.count(),
|
||||
evolution_triggers=EvolutionTrigger.objects.count(),
|
||||
evolution_trigger_names=EvolutionTriggerName.objects.count(),
|
||||
experiences=Experience.objects.count(),
|
||||
generations=Generation.objects.count(),
|
||||
generation_names=GenerationName.objects.count(),
|
||||
genders=Gender.objects.count(),
|
||||
growth_rates=GrowthRate.objects.count(),
|
||||
growth_rate_descriptions=GrowthRateDescription.objects.count(),
|
||||
items=Item.objects.count(),
|
||||
item_names=ItemName.objects.count(),
|
||||
item_effect_texts=ItemEffectText.objects.count(),
|
||||
item_categories=ItemCategory.objects.count(),
|
||||
item_category_names=ItemCategoryName.objects.count(),
|
||||
item_attributes=ItemAttribute.objects.count(),
|
||||
item_attribute_maps=ItemAttributeMap.objects.count(),
|
||||
item_attribute_descriptions=ItemAttributeDescription.objects.count(),
|
||||
item_flavor_texts=ItemFlavorText.objects.count(),
|
||||
item_fling_effects=ItemFlingEffect.objects.count(),
|
||||
item_fling_effect_effect_texts=ItemFlingEffectEffectText.objects.count(),
|
||||
item_pockets=ItemPocket.objects.count(),
|
||||
item_pocket_names=ItemPocketName.objects.count(),
|
||||
item_game_indexes=ItemGameIndex.objects.count(),
|
||||
languages=Language.objects.count(),
|
||||
language_names=LanguageName.objects.count(),
|
||||
locations=Location.objects.count(),
|
||||
location_game_indexes=LocationGameIndex.objects.count(),
|
||||
location_names=LocationName.objects.count(),
|
||||
location_areas=LocationArea.objects.count(),
|
||||
location_area_names=LocationAreaName.objects.count(),
|
||||
location_area_encounter_rates=LocationAreaEncounterRate.objects.count(),
|
||||
machines=Machine.objects.count(),
|
||||
moves=Move.objects.count(),
|
||||
move_names=MoveName.objects.count(),
|
||||
move_changes=MoveChange.objects.count(),
|
||||
move_flavor_text=MoveFlavorText.objects.count(),
|
||||
move_effects=MoveEffect.objects.count(),
|
||||
move_effect_changes=MoveEffectChange.objects.count(),
|
||||
move_effect_change_effect_texts=MoveEffectChangeEffectText.objects.count(),
|
||||
move_effect_effect_texts=MoveEffectEffectText.objects.count(),
|
||||
move_attributes=MoveAttribute.objects.count(),
|
||||
move_attribute_names=MoveAttributeName.objects.count(),
|
||||
move_attribute_maps=MoveAttributeMap.objects.count(),
|
||||
move_attribute_descriptions=MoveAttributeDescription.objects.count(),
|
||||
move_metas=MoveMeta.objects.count(),
|
||||
move_ailments=MoveMetaAilment.objects.count(),
|
||||
move_ailment_names=MoveMetaAilmentName.objects.count(),
|
||||
move_battle_styles=MoveBattleStyle.objects.count(),
|
||||
move_battle_style_names=MoveBattleStyleName.objects.count(),
|
||||
move_categories=MoveMetaCategory.objects.count(),
|
||||
move_damage_classes=MoveDamageClass.objects.count(),
|
||||
move_damage_class_descriptions=MoveDamageClassDescription.objects.count(),
|
||||
move_learn_methods=MoveLearnMethod.objects.count(),
|
||||
move_learn_method_names=MoveLearnMethodName.objects.count(),
|
||||
move_targets=MoveTarget.objects.count(),
|
||||
move_target_descriptions=MoveTargetDescription.objects.count(),
|
||||
move_state_changes=MoveMetaStatChange.objects.count(),
|
||||
natures=Nature.objects.count(),
|
||||
nature_names=NatureName.objects.count(),
|
||||
nature_pokeathlon_stats=NaturePokeathlonStat.objects.count(),
|
||||
nature_battle_style_preference=NatureBattleStylePreference.objects.count(),
|
||||
pal_park_areas=PalParkArea.objects.count(),
|
||||
pal_park_area_names=PalParkAreaName.objects.count(),
|
||||
pal_parks=PalPark.objects.count(),
|
||||
pokeathlon_stat_names=PokeathlonStatName.objects.count(),
|
||||
pokeathlon_stats=PokeathlonStat.objects.count(),
|
||||
pokedexes=PokedexVersionGroup.objects.count(),
|
||||
pokedex_descriptions=PokedexDescription.objects.count(),
|
||||
pokedex_version_groups=PokedexVersionGroup.objects.count(),
|
||||
pokemon=Pokemon.objects.count(),
|
||||
pokemon_abilities=PokemonAbility.objects.count(),
|
||||
pokemon_colors=PokemonColor.objects.count(),
|
||||
pokemon_names=PokemonColorName.objects.count(),
|
||||
pokemon_dex_numbers=PokemonDexNumber.objects.count(),
|
||||
pokemon_egg_groups=PokemonEggGroup.objects.count(),
|
||||
pokemon_evolutions=PokemonEvolution.objects.count(),
|
||||
pokemon_forms=PokemonForm.objects.count(),
|
||||
pokemon_form_names=PokemonFormName.objects.count(),
|
||||
pokemon_form_generations=PokemonFormGeneration.objects.count(),
|
||||
pokemon_game_indices=PokemonGameIndex.objects.count(),
|
||||
pokemon_habitats=PokemonHabitat.objects.count(),
|
||||
pokemon_habitat_names=PokemonHabitatName.objects.count(),
|
||||
pokemon_items=PokemonItem.objects.count(),
|
||||
pokemon_moves=PokemonMove.objects.count(),
|
||||
pokemon_shapes=PokemonShape.objects.count(),
|
||||
pokemon_shape_names=PokemonShapeName.objects.count(),
|
||||
pokemon_species=PokemonSpecies.objects.count(),
|
||||
pokemon_species_names=PokemonSpeciesName.objects.count(),
|
||||
pokemon_descriptions=PokemonSpeciesDescription.objects.count(),
|
||||
pokemon_flavor_texts=PokemonSpeciesFlavorText.objects.count(),
|
||||
pokemon_stat=PokemonStat.objects.count(),
|
||||
pokemon_type=PokemonType.objects.count(),
|
||||
regions=Region.objects.count(),
|
||||
region_names=RegionName.objects.count(),
|
||||
stats=Stat.objects.count(),
|
||||
stat_names=StatName.objects.count(),
|
||||
super_contest_effects=SuperContestEffect.objects.count(),
|
||||
super_contest_combos=SuperContestCombo.objects.count(),
|
||||
super_contest_effect_flavor_texts=SuperContestEffectFlavorText.objects.count(),
|
||||
types=Type.objects.count(),
|
||||
type_names=TypeName.objects.count(),
|
||||
type_game_indices=TypeGameIndex.objects.count(),
|
||||
type_efficacy=TypeEfficacy.objects.count(),
|
||||
versions=Version.objects.count(),
|
||||
version_names=VersionName.objects.count(),
|
||||
version_groups=VersionGroup.objects.count(),
|
||||
version_group_move_learn_methods=VersionGroupMoveLearnMethod.objects.count(),
|
||||
version_group_regions=VersionGroupRegion.objects.count(),
|
||||
)
|
||||
|
||||
lines = 0
|
||||
for i in data.iteritems():
|
||||
lines += i[1]
|
||||
|
||||
resources = 0
|
||||
resources += data['abilities']
|
||||
resources += data['berries']
|
||||
resources += data['berry_flavors']
|
||||
resources += data['berry_firmnesses']
|
||||
resources += data['characteristics']
|
||||
resources += data['contest_types']
|
||||
resources += data['contest_effects']
|
||||
resources += data['egg_groups']
|
||||
resources += data['encounter_methods']
|
||||
resources += data['encounter_conditions']
|
||||
resources += data['encounter_condition_values']
|
||||
resources += data['evolution_chains']
|
||||
resources += data['evolution_triggers']
|
||||
resources += data['generations']
|
||||
resources += data['genders']
|
||||
resources += data['growth_rates']
|
||||
resources += data['items']
|
||||
resources += data['item_attributes']
|
||||
resources += data['item_categories']
|
||||
resources += data['item_fling_effects']
|
||||
resources += data['item_pockets']
|
||||
resources += data['languages']
|
||||
resources += data['locations']
|
||||
resources += data['location_areas']
|
||||
resources += data['moves']
|
||||
resources += data['move_ailments']
|
||||
resources += data['move_categories']
|
||||
resources += data['move_battle_styles']
|
||||
resources += data['move_damage_classes']
|
||||
resources += data['move_learn_methods']
|
||||
resources += data['move_targets']
|
||||
resources += data['natures']
|
||||
resources += data['pal_park_areas']
|
||||
resources += data['pokedexes']
|
||||
resources += data['pokemon']
|
||||
resources += data['pokemon_colors']
|
||||
resources += data['pokemon_forms']
|
||||
resources += data['pokemon_habitats']
|
||||
resources += data['pokemon_shapes']
|
||||
resources += data['pokemon_species']
|
||||
resources += data['pokeathlon_stats']
|
||||
resources += data['regions']
|
||||
resources += data['stats']
|
||||
resources += data['super_contest_effects']
|
||||
resources += data['types']
|
||||
resources += data['versions']
|
||||
resources += data['version_groups']
|
||||
|
||||
data['total_lines'] = lines
|
||||
data['total_resources'] = resources
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def about(request):
|
||||
|
||||
site_data = _total_site_data()
|
||||
|
||||
total_views = ResourceView.objects.total_count()
|
||||
total_v1_views = ResourceView.objects.total_count(version=1)
|
||||
total_v2_views = ResourceView.objects.total_count(version=2)
|
||||
|
||||
average_day = int(round(total_views / ResourceView.objects.count()))
|
||||
|
||||
|
@ -235,10 +21,7 @@ def about(request):
|
|||
'pages/about.html',
|
||||
{
|
||||
'total': total_views,
|
||||
'total_v1': total_v1_views,
|
||||
'total_v2': total_v2_views,
|
||||
'average_day': average_day,
|
||||
'site_data': site_data,
|
||||
},
|
||||
context_instance=RequestContext(request)
|
||||
)
|
||||
|
|
|
@ -3,7 +3,7 @@ from django.db import models
|
|||
from datetime import date
|
||||
|
||||
|
||||
class ViewManager(models.Manager):
|
||||
class ResourceViewManager(models.Manager):
|
||||
|
||||
def increment_view_count(self, version):
|
||||
|
||||
|
@ -14,30 +14,21 @@ class ViewManager(models.Manager):
|
|||
|
||||
view.count = view.count + 1
|
||||
|
||||
print view
|
||||
|
||||
view.save()
|
||||
|
||||
def total_count(self, version=0):
|
||||
|
||||
if version:
|
||||
objects = ResourceView.objects.filter(version=version)
|
||||
else:
|
||||
objects = ResourceView.objects.all()
|
||||
all_hits = ResourceView.objects.all().values_list('count', flat=True)
|
||||
|
||||
t = 0
|
||||
for v in objects:
|
||||
t += v.count
|
||||
|
||||
return t
|
||||
return sum(all_hits)
|
||||
|
||||
|
||||
class ResourceView(models.Model):
|
||||
|
||||
objects = ViewManager()
|
||||
objects = ResourceViewManager()
|
||||
|
||||
def __unicode__(self):
|
||||
return str(self.date) + ' - ' + str(self.count)
|
||||
return '{} - {}'.format(str(self.date), str(self.count))
|
||||
|
||||
count = models.IntegerField(max_length=1000, default=0)
|
||||
version = models.IntegerField(max_length=1, default=1)
|
||||
|
|
|
@ -9,7 +9,7 @@ from hits.models import ResourceView
|
|||
|
||||
|
||||
###########################
|
||||
# BEHAVOIR ABSTRACTIONS #
|
||||
# BEHAVIOR ABSTRACTIONS #
|
||||
###########################
|
||||
|
||||
class ListOrDetailSerialRelation():
|
||||
|
|
|
@ -2974,7 +2974,7 @@ class PokedexDetailSerializer(serializers.ModelSerializer):
|
|||
|
||||
def get_pokedex_entries(self, obj):
|
||||
|
||||
results = PokemonDexNumber.objects.order_by('pokedex_number').filter(pokedex=obj)
|
||||
results = PokemonDexNumber.objects.filter(pokedex=obj).order_by('pokedex_number')
|
||||
serializer = PokemonDexNumberSerializer(results, many=True, context=self.context)
|
||||
data = serializer.data
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ django-imagekit==3.2.4
|
|||
django-tastypie==0.12.1
|
||||
django-markdown-deux==1.0.5
|
||||
djangorestframework>=3.1.0
|
||||
drf-ujson==1.2.0
|
||||
gunicorn==0.17.0
|
||||
markdown2==2.3.0
|
||||
mimeparse==0.1.3
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
</p>
|
||||
<div class="well">
|
||||
<p>
|
||||
This website provides a RESTful API interface to <b>{{ site_data.total_resources|intcomma }}</b> highly detailed objects built from <b>{{ site_data.total_lines|intcomma }}</b> lines of data
|
||||
This website provides a RESTful API interface to highly detailed objects built from thousands of lines of data
|
||||
related to <a href="https://en.wikipedia.org/wiki/Pokemon">Pokémon</a>. We specifically cover the video game franchise, though we'd like to cover the card game too. Using this website you can consume information on Pokémon, their moves, abilities, types, egg groups and much much more.
|
||||
</p>
|
||||
</div>
|
||||
|
@ -57,7 +57,7 @@
|
|||
This is probably worth clearing up very quickly for those who don't know.<br />
|
||||
An API (Application Programming Interface) is a set of interfaces (in this case, url links)
|
||||
that are publicly available, that allow developers to interact with an application.<br />
|
||||
In this instance; the application is a database of <b>{{ site_data.total_items|intcomma }}</b> pokemon-related objects.
|
||||
In this instance; the application is a database of thousands oc pokemon-related objects.
|
||||
</p>
|
||||
</div>
|
||||
<p class="lead">
|
||||
|
|
Loading…
Add table
Reference in a new issue