我正在为锻炼创建一个跟踪应用程序,我想知道创建模型的最有效方法。我做的大多数练习都有重复,组合和重量。但是有一些有距离和时间的跑步。起初,我打算创建两个不同的模型来捕获每个模型,但后来我觉得组合起来可能会更好。现在,我不确定。
好的,下面是我的第一遍:
LEVELS = (
(1, '1 - Hardly'),
(2, '2'),
(3, '3'),
(4, '4'),
(5, '5 - Average'),
(6, '6'),
(7, '7'),
(8, '8'),
(9, '9'),
(10, '10 - Very'),
class Jog(models.Model):
distance = models.DecimalField("Distance (Miles)", max_digits=4, decimal_places=2)
time = models.DecimalField("Time (Minutes)", max_digits=4, decimal_places=2)
intensity = models.IntegerField("Intensity", choices = LEVELS, default = 5)
date = models.DateTimeField("Date", blank=True, default=datetime.now)
notes = models.TextField("Notes", blank=True)
def __str__(self):
return "%s Miles in %s Minutes (Intensity of %s)" % (self.distance, self.time, self.intensity)
class Meta:
verbose_name = "Jog"
class Exercise_Type(models.Model):
name = models.CharField("Exercise Name", max_length=200, unique = True)
slug = models.SlugField(max_length=100, blank=True)
notes = models.TextField("Notes", blank=True)
def __str__(self):
return self.name
class Workout(models.Model):
exercise_type = models.ForeignKey(Exercise_Type, verbose_name="Exercise Type")
reps = models.IntegerField("Repetitions")
sets = models.DecimalField("Sets", max_digits=2, decimal_places=1)
weight = models.IntegerField("Weight", blank=True, null=True)
intensity = models.IntegerField("Intensity", choices = LEVELS, default = 5)
date = models.DateTimeField("Date", blank=True, default=datetime.now)
notes = models.TextField("Notes", blank=True)
这看起来很愚蠢,因为慢跑是一种锻炼方式,因为它具有不同的测量特征而只能被分开。那么我想,如果我做这样的事情怎么办?在锻炼类型中定义必要的字段,然后通过询问用户锻炼类型来启用/禁用它们:
class Exercise_Type(models.Model):
name = models.CharField("Exercise Name", max_length=200, unique = True)
slug = models.SlugField(max_length=100, blank=True)
notes = models.TextField("Notes", blank=True)
distance = models.BooleanField("Use Distance Field?", default = False)
time = models.BooleanField("Use Time Field?", default = False)
reps = models.BooleanField("Use Reps Field", default = False)
sets = models.BooleanField("Use Sets Field?", default = False)
weight = models.BooleanField("Use Weight Field?", default = False)
def __str__(self):
return self.name
class Workout(models.Model):
exercise_type = models.ForeignKey(Exercise_Type, verbose_name="Exercise Type")
distance = models.DecimalField("Distance (Miles)", max_digits=4, decimal_places=2, blank = True, null=True)
time = models.DecimalField("Time (Minutes)", max_digits=4, decimal_places=2, blank = True, null=True)
reps = models.IntegerField("Repetitions", blank = True, null=True)
sets = models.DecimalField("Sets", max_digits=2, decimal_places=1, blank = True, null=True)
weight = models.IntegerField("Weight", blank=True, null=True)
intensity = models.IntegerField("Intensity", choices = LEVELS, default = 5)
date = models.DateTimeField("Date", blank=True, default=datetime.now)
notes = models.TextField("Notes", blank=True)
这似乎是浪费资源,因为无论是否需要,每项练习在技术上都会占据各个领域。
然后我想,子分类怎么样?就在那时我放弃了,并决定吸引那些比我更有知识的人。
组织此模型的最佳方法是什么?
答案 0 :(得分:1)
由于每个练习都有一个或多个要测量的属性,因此您应该提取这些属性,因此最终会得到三个主要模型。
class Metric(models.Model):
name = models.CharField(max_length=20)
description = models.TextField(null=True, blank=True)
measured_in = models.CharField(max_length=20, null=True, blank=True)
# other fields
class Measurement(models.Model):
metric = models.ForeignKey(Metric)
value = models.CharField(max_length=20, null=True, blank=True)
workout_date = models.DateField(auto_now=True)
class Workout(models.Model):
# common attributes for each workout
name = models.CharField(max_length=200)
notes = models.TextField()
metrics = models.ManyToManyField(Measurement)
您可以向Metric
添加各种指标(您衡量的内容)。对于每个锻炼,您可以通过添加创建新Measurement
来确定要跟踪的指标。最后,您在创建它时将其与每个锻炼相关联。
以下是一个示例:
reps = Metric.objects.create(name='Reps')
my_reps = Measurement.objects.create(metric=reps,value=10)
w = Workout(name="Weights")
w.metrics.add(my_reps)
w.save()
答案 1 :(得分:1)
这正是继承的目的。创建一个通用的Workout
类型,然后将其与运动类型子类化。使用子类上的唯一/特定属性。
class Workout(models.Model):
date = models.DateTimeField("Date", blank=True, default=datetime.now)
notes = models.TextField("Notes", blank=True)
class Jog(Workout):
distance = models.DecimalField("Distance (Miles)", max_digits=4, decimal_places=2, blank = True, null=True)
time = models.DecimalField("Time (Minutes)", max_digits=4, decimal_places=2, blank = True, null=True)
class Weightlifting(Workout):
reps = models.IntegerField("Repetitions", blank = True, null=True)
sets = models.DecimalField("Sets", max_digits=2, decimal_places=1, blank = True, null=True)
weight = models.IntegerField("Weight", blank=True, null=True)
等等。如果您不需要在任何地方使用通用Workout
类型,则可以将其设置为抽象模型。