1

運動用の追跡アプリケーションを作成していますが、モデルを作成する最も効率的な方法について疑問に思っています。私が行うほとんどのエクササイズには、繰り返し、セット、ウェイトがあります。しかし、距離と時間のあるランもあります。最初は2つの異なるモデルを作成してそれぞれをキャプチャするつもりでしたが、組み合わせたほうがよいのではないかと考えました。さて、よくわかりません。

わかりました、以下は私の最初のパスです:

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

これはまさに継承が行われるものです。ジェネリック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 に答える
1

各演習には、測定したい 1 つ以上のプロパティがあるため、それらのプロパティを抽出する必要があります。これにより、最終的に 3 つの主要なモデルが得られます。

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 に答える