1. John Costa
  2. django-fitlog

Source

django-fitlog / fitlog / models.py

from django.db import models
from django.contrib.auth.models import User
from fitlog.utils import addDateTimes

from fitlog.choices import WEIGHT_CHOICES, REP_CHOICES, GENDER_CHOICES
from fitlog.managers import (
    FitLogManager, CardioManager, WeightManager, BodyWeightLogManager)

class UserProfile(models.Model):
     
  # This is the only required field
  user = models.ForeignKey(User, unique=True)
  gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
  
  def __unicode__(self):
      return u'%s' % self.user.username

class Team(models.Model):
    name = models.CharField(max_length=50)
    description = models.TextField(max_length=255,blank=True)
    
class FitLog(models.Model):
    member = models.ForeignKey(User)
    create_date = models.DateTimeField(auto_now_add=True)
    last_update = models.DateTimeField(auto_now=True)
    log_date = models.DateField()
    total_time = models.TimeField(blank=True, null=True)
    title = models.CharField(max_length=255)
    comments = models.TextField(max_length=5000,blank=True)
    
    objects = FitLogManager()
    
    def __init__(self, *args, **kwargs):
        super(FitLog,self).__init__(*args,**kwargs)
        self.__total_exercises = None
        self.__total_sets = None
        self.__total_reps = None
        self.__training_volume = None
        self.__cardio_min = None
        self.__cardio_distance = None
        self.__calculated = False        
    
    def __calculate_totals(self):
        if not self.__calculated:
            if self.weightfitlogdetail_set:
                self.__total_exercises = self.weightfitlogdetail_set.count()
            else:
                self.__total_exercises = 0



            if self.weightfitlogdetail_set:
                wl = self.weightfitlogdetail_set.all()
                for w in wl:
                    wdl = w.weightlogset_set.all()
                    for wd in wdl:
                        if not self.__total_sets:
                            self.__total_sets = 0
                        if not self.__total_reps:
                            self.__total_reps = 0
                        if not self.__training_volume:
                            self.__training_volume = 0
                                    
                        self.__total_sets = self.__total_sets + 1                            
                        self.__total_reps = self.__total_reps + wd.reps
                        if wd.reps and wd.weight:
                            self.__training_volume = self.__training_volume + (wd.reps * wd.weight )                        
    
            if self.cardiofitlogdetail_set:
                cl = self.cardiofitlogdetail_set.all()
                for c in cl:
                        if not self.__cardio_min:
                            self.__cardio_min = 0
                        if not self.__cardio_distance:
                            self.__cardio_distance = 0
                                                                
                        self.__cardio_min = addDateTimes(self.__cardio_min,c.total_time)
                        self.__cardio_distance = self.__cardio_distance + c.distance
                
            self.__calculated = True
            
    
    @property
    def total_exercises(self):
        if not self.__total_exercises:
            self.__calculate_totals()
        return self.__total_exercises
    
    @property
    def total_sets(self):
        if not self.__total_sets:
            self.__calculate_totals()    
        return self.__total_sets
    
    @property
    def total_reps(self):
        if not self.__total_reps:
            self.__calculate_totals()    
        return self.__total_reps
    
    @property
    def training_volume(self):
        if not self.__training_volume:
            self.__calculate_totals()    
        return self.__training_volume
    
    @property
    def cardio_min(self):
        if not self.__cardio_min:
            self.__calculate_totals()    
        return self.__cardio_min
    
    @property
    def cardio_distance(self):
        if not self.__cardio_distance:
            self.__calculate_totals()    
        return self.__cardio_distance
    
class FitnessType(models.Model):
    name = models.CharField(max_length=50)
    
    def __unicode__(self):
      return self.name

class MuscleGroup(models.Model):
    name = models.CharField(max_length=100)
    
    def __unicode__(self):
      return self.name

class ExerciseType(models.Model):
    fitness_type = models.ForeignKey(FitnessType)
    muscle_group = models.ForeignKey(MuscleGroup,blank=True,null=True)
    name = models.CharField(max_length=50)
    
    cardio_objects = CardioManager()
    weight_objects = WeightManager()
    
    def __unicode__(self):
        if self.muscle_group:
            name = "[%s]  %s" % (self.muscle_group.name,self.name)
        else:
            name = "%s " % (self.name)
        return name
    
class FitLogDetail(models.Model):
    fit_log = models.ForeignKey(FitLog)
    exercise_type = models.ForeignKey(ExerciseType)
    comments = models.CharField(max_length=500,blank=True)
    
    class Meta:
        abstract = True
    
class CardioFitLogDetail(FitLogDetail):
    total_time = models.TimeField(blank=True, null=True)
    distance = models.DecimalField(max_digits=5,decimal_places=1)
 
#TODO PERFORMANCE : Make this better..
class WeightFitLogDetail(FitLogDetail):
    __weights = None
    
    def __get_weightlogset(self):
        if not self.__weights:
            self.__weights = self.weightlogset_set.all()
        return self.__weights
    
    def get_weights(self):
        weights = self.__get_weightlogset()
        out = None
        for w in weights:
            if not out:
                out = "%s" % w.weight
            else:
                out = out + "/%s" % w.weight
            
        return out
    
    def get_reps(self):
        weights = self.__get_weightlogset()
        out = None
        for w in weights:
            if not out:
                out = "%s" % w.reps
            else:
                out = out + "/%s" % w.reps

        return out


class WeightLogSet(models.Model):
    weight_log_detail = models.ForeignKey(WeightFitLogDetail)
    sequence = models.SmallIntegerField()
    weight = models.SmallIntegerField(choices=WEIGHT_CHOICES)
    reps = models.SmallIntegerField(choices=REP_CHOICES)



class BodyWeightLog(models.Model):
    member = models.ForeignKey(User)
    weight = models.DecimalField(max_digits=5,decimal_places=1)
    weight_date = models.DateField()
    comments = models.TextField(max_length=5000,blank=True)
    
    objects = BodyWeightLogManager()