2016-12-29 5 views
1

사용자 ID를 기반으로 통계를 집계 할 테이블을 작성하려고합니다. 질문을하는 것은 이번이 처음이기 때문에 중요한 것을 놓친다면 나와 함께 감내하십시오. 여기 Django 집계 된 합계를 계산하십시오.

class Batting(models.Model): 
    player = models.ForeignKey(
    'Player', 
    on_delete=models.CASCADE, 
    null=True, 
    ) 
    game = models.ForeignKey(
    'Game', 
    on_delete=models.CASCADE, 
    null=True, 
    blank=True, 
    ) 
    season = models.ForeignKey(
    'Season', 
    on_delete=models.CASCADE, 
    null=True, 
    ) 
    games_played = models.IntegerField(
    blank=True, 
    default=1, 
    ) 
    plate_appearances = models.IntegerField(
    blank=True, 
    default=0, 
    ) 
    at_bats = models.DecimalField(
    default=0, 
    max_digits=6, 
    decimal_places=3, 
    ) 
    hits = models.DecimalField(
    blank=True, 
    max_digits=6, 
    decimal_places=3, 
    default=0, 
    ) 
    ... 
    batting_average = models.DecimalField(
    max_digits=6, 
    decimal_places=3, 
    editable=False, 
    null=True 
    ) 
    slugging_percentage = models.DecimalField(
    max_digits=6, 
    decimal_places=3, 
    editable=False, 
    null=True 
    ) 
    on_base_percentage = models.DecimalField(
    max_digits=6, 
    decimal_places=3, 
    editable=False, 
    null=True 
    ) 
    on_base_plus_slugging_percentage = models.DecimalField(
    max_digits=6, 
    decimal_places=3, 
    editable=False, 
    null=True 
    ) 

    def save(self, *args, **kwargs): 
     self.total_bases = self.singles + (self.doubles * 2) + (self.triples * 3) + (self.home_runs * 4) 
     self.extra_base_hits = self.doubles + self.triples + self.home_runs 
     self.batting_average = float(self.hits)/float(self.at_bats) 
     self.slugging_percentage = self.total_bases/float(self.at_bats) 
     self.on_base_percentage = (self.hits + self.base_on_balls + self.hit_by_pitch)/float(self.at_bats + self.base_on_balls + self.sacrifice_flys + self.hit_by_pitch) 
     self.on_base_plus_slugging_percentage = (self.hits + self.base_on_balls + self.hit_by_pitch)/float(self.at_bats + self.base_on_balls + self.sacrifice_flys + self.hit_by_pitch) 
     super(Batting, self).save(*args, **kwargs) 

    class Meta: 
    verbose_name = u'Batting Stat' 
    verbose_name_plural = u'Batting Stats' 

    def __unicode__(self): 
    return self.player.last_name 

뷰입니다 : 여기

모델입니다

def stats(request): 
    batting_stats = Batting.objects.values('player__id').annotate(
    fn=F('player__first_name'), 
    ln=F('player__last_name'), 
    total_hits=Sum(('hits'),output_field=FloatField()), 
    total_at_bats=Sum(('at_bats'),output_field=FloatField()), 
    avg=Avg('batting_average'), 
    slg=Avg('slugging_percentage'), 
    obp=Avg('on_base_percentage'), 
    ops=Avg('on_base_plus_slugging_percentage'), 
    ) 

    return render(request, 'stats.html', { 
    'batting_stats': batting_stats, 
    }) 

내가 만난 문제는 그 평균, 장타율, 출루율, 그리고 작전은 모델의 모든 계산이다 , View에서 평균화하는 것은 플레이어 ID를 기반으로 집계되는 합계를 계산하는 것과는 대조적으로 평균을 평균합니다.

집계 함수를 사용해 보았지만 작동하게 만들 수있는 방법을 찾지 못했습니다. Annotate와 Aggregate를 결합하여 단일 Player ID로 통계를 통합하고 동일한 계산을 총계에 적용 할 수있는 방법이 있습니까?

답변

0

실제로 볼 수 있듯이 단일 타격 인스턴스와 통계보기에 대해 똑같은 계산이 필요합니다. 그래서 하나의 함수에서 그것을하고 두 지점에서 전화 할게 :이 100 % 유효한 코드가 아닙니다

def count_averages(data, result_recipient=None): 
    result_recipient = data if result_recipient=None else result_recipient 
    result_recipient.total_bases = data.singles + (data.doubles * 2) + (data.triples * 3) + (data.home_runs * 4) 
    result_recipient.extra_base_hits = data.doubles + data.triples + data.home_runs 
    ... 

def save(self, *args, **kwargs): 
    count_averages(self) 
    super(Batting, self).save(*args, **kwargs) 

def stats(request): 
    sum_of_all_batting_stats = Batting.objects.filter('player__id'=player__id).annotate(
     sum('singles'), 
     sum('doubles'), 
     sum('triples'), 
     ... 
    ) 
    batting_stats = {} 
    count_averages(self, batting_stats) 

    return render(request, 'stats.html', { 
     'batting_stats': batting_stats, 
    }) 

, 그러나 당신은 생각을 가지고해야합니다 : 당신은 분리 기능 통화로 계산을 이동 2 개의 다른 데이터 - 1) 하나의 타격 인스턴스와 2) 모든 타격 인스턴스의 합계.

P. 모든보기 호출마다 매번 계산하면 성능 문제가 발생할 수 있습니다. db 테이블 또는 일부 캐시에 집계 된 통계를 저장하는 것이 좋습니다.

+0

응답 해 주셔서 감사합니다 .-이 질문은 친구와 어젯밤에했던 토론에서 얻은 답변과 매우 흡사합니다. 그래서 나는 (귀하의 예에서 도움을 받아) 그것에 접근하는 방법에 대한 좋은 아이디어가 있다고 생각합니다. – whob13