I am working on a stats website for my softball teams that I manage/play for.
Here is my current Stat model:
class Stat(models.Model):
player = models.ForeignKey(Player)
game = models.ForeignKey(Game)
team = models.ForeignKey(Team)
batting_order = models.IntegerField(default=1)
plate_apperences = models.IntegerField(default=0, verbose_name='PA')
runs = models.IntegerField(default=0, verbose_name='R')
singles = models.IntegerField(default=0, verbose_name='1B')
doubles = models.IntegerField(default=0, verbose_name='2B')
triples = models.IntegerField(default=0, verbose_name='3B')
home_runs = models.IntegerField(default=0, verbose_name='HR')
runs_batted_in = models.IntegerField(default=0, verbose_name='RBI')
walks = models.IntegerField(default=0, verbose_name='BB')
sacrifice_flies = models.IntegerField(default=0, verbose_name='SAC')
fielders_choice = models.IntegerField(default=0, verbose_name='FC')
reached_base_on_error = models.IntegerField(default=0,
verbose_name='RBOE')
@property
def at_bats(self):
return (self.plate_apperences -
(self.walks + self.sacrifice_flies + self.reached_base_on_error))
@property
def hits(self):
return self.singles + self.doubles + self.triples + self.home_runs
@property
def total_bases(self):
return (self.plate_apperences -
(self.walks + self.sacrifice_flies + self.reached_base_on_error))
@property
def batting_average(self):
return round(self.hits / self.at_bats, 3)
@property
def on_base_percentage(self):
if self.at_bats + self.walks + self.sacrifice_flies == 0:
return 0.000
return (round(((self.hits + self.walks)
/(self.at_bats + self.walks + self.sacrifice_flies) ), 3))
@property
def slugging_percentage(self):
return round(self.total_bases / self.at_bats, 3)
@property
def runs_created(self):
return round(self.on_base_percentage + self.total_bases, 0)
@property
def total_base_percentage(self):
return int(round((self.hits + self.walks)
/ (self.at_bats + self.walks), 3))
def __str__(self):
if self.game.home:
return ("{} - {} vs {} - {}.{}".format(
self.game.date.strftime('%Y/%m/%d'), self.team.name,
self.game.opponent, self.player.last_name,
self.player.first_name[0]))
else:
return ("{} - {} @ {} - {}.{}".format(
self.game.date.strftime('%Y/%m/%d'),self.game.team.name,
self.game.opponent, self.player.last_name,
self.player.first_name[0]))
class Meta:
ordering = ['-game', 'batting_order']
This returns me the data I need... but it is always on a per game basis. What I am looking to do is have 3 options. Stats for: Player, game, and team.
If I select the player button, I will get a player drop down where after selecting a player I will get the players totaled stats per year (50-75 total at bats).
If I select the game button, I should get a team drop down, then a game drop down, then the stats for that game should show all players who played in that game and their stats (talking 3-4 at bats per player)
If I select the team button, I should get a drop down of all my teams, where after selecting one it should show all the players that played for that team (team is comprised of year/team name/week night) and their totaled stats for the year. So, we are talking 10-25 players each with anywhere from 4-75 at bats.
Right now no matter if I select player, game, or team, the stats are individual to a player/game relation. Is there a easy way to query to get a total or do I need a bunch of redundent code to make a TeamStat and PLayerStat api url.
Again for player I would like a season total by team, not stats by game. So for the image above I would want to see just 1 row of totaled stats (I would need to add a team drop down as well):
Year | Team | PA | AB | R | H | ...
2017 | Brew Berlin | 7 | 6 | 2 | 6 | ...
To help show what I am doing here are my serialzers and urls.
Serializers:
class PlayerSerializer(serializers.ModelSerializer):
short_name = serializers.CharField(max_length=100)
long_name = serializers.CharField(max_length=100)
class Meta:
model = Player
fields = '__all__'
class TeamSerializer(serializers.ModelSerializer):
manager = ManagerSerializer(read_only=True)
league = LeagueSerializer(read_only=True)
players = PlayerSerializer(read_only=True, many=True)
display_name = serializers.CharField(max_length=100)
class Meta:
model = Team
fields = '__all__'
class GameSerializer(serializers.ModelSerializer):
team = TeamSerializer(read_only=True)
class Meta:
model = Game
fields = '__all__'
class StatSerializer(serializers.ModelSerializer):
player = PlayerSerializer(read_only=True)
game = GameSerializer(read_only=True)
at_bats = serializers.IntegerField()
hits = serializers.IntegerField()
total_bases = serializers.IntegerField()
batting_average = serializers.DecimalField(max_digits=4,
decimal_places=3)
on_base_percentage = serializers.DecimalField(max_digits=4,
decimal_places=3)
slugging_percentage = serializers.DecimalField(max_digits=4,
decimal_places=3)
runs_created = serializers.IntegerField()
total_base_percentage = serializers.DecimalField(max_digits=4,
decimal_places=3)
class Meta:
model = Stat
fields = '__all__'
And here is my current routing:
from rest_framework_nested import routers
from django.conf.urls import url, include
from .api import LeagueViewSet, ManagerViewSet, TeamViewSet, PlayerViewSet
from .api import AwardTypeViewSet, AwardViewSet, GameViewSet, StatViewSet
from .api import GameStatViewSet, PlayerStatViewSet, TeamStatViewSet
#router = DefaultRouter()
router = routers.DefaultRouter()
router.register(r'leagues', LeagueViewSet)
router.register(r'managers', ManagerViewSet)
router.register(r'teams', TeamViewSet, base_name='teams')
router.register(r'players', PlayerViewSet, base_name='players')
router.register(r'awardtypes', AwardTypeViewSet)
router.register(r'games', GameViewSet, base_name='games')
router.register(r'stats', StatViewSet)
team_router = routers.NestedSimpleRouter(router, r'teams', lookup='team')
team_router.register(r'awards', AwardViewSet, base_name='awards')
team_router.register(r'games', GameViewSet, base_name='games')
team_router.register(r'stats', TeamStatViewSet, base_name='stats')
team_router.register(r'players', PlayerViewSet, base_name='players')
game_router = routers.NestedSimpleRouter(router, r'games', lookup='game')
game_router.register(r'stats', GameStatViewSet, base_name='stats')
player_router = routers.NestedSimpleRouter(router, r'players',
lookup='player')
player_router.register(r'stats', PlayerStatViewSet, base_name='stats')
urlpatterns = [
url(r'^', include(router.urls)),
url(r'^', include(team_router.urls)),
url(r'^', include(game_router.urls)),
url(r'^', include(player_router.urls)),
]
Sorry for the huge post, just trying to give as much helpful info as possible. Thanks for any input.
P.S. This is my first python/django app. I normally code in .net, so if I am way off on my DRF let me know.

