1

我正在为锻炼创建一个跟踪应用程序,我想知道创建模型的最有效方法。我做的大多数练习都有重复、组和重量。但是有些跑步有距离和时间。起初,我打算创建两个不同的模型来捕捉每个模型,但后来我认为合并起来可能会更好。现在,我不确定。

好的,下面是我的第一关:

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)

这似乎是一种资源浪费,因为从技术上讲,无论是否需要,每次练习都会涉及每个领域。

然后我想,子分类呢?就在那时,我放弃了,决定吸引那些比我更有知识的人。

组织这个模型的最佳方式是什么?

4

2 回答 2

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()
于 2012-05-08T21:12:47.933 回答
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任何地方使用泛型类型,则可以将其设为抽象模型。

于 2012-05-08T21:20:05.627 回答