2012-05-08 11 views
1

私は練習用の追跡アプリケーションを作成しており、モデルを作成する最も効率的な方法については疑問に思っています。ほとんどの練習には繰り返し、セット、ウェイトがあります。しかし、そこに距離と時間を持つ実行されます。最初は、それぞれをキャプチャするために2つの異なるモデルを作成するつもりでしたが、次にそれを組み合わせる方が良いと考えました。今、私はよくわからない。Djangoモデルの適切な構築

以下、[OK]を、私の最初のパスである:ジョグは、ワークアウトのタイプであり、それは別の測定特性を持っているので、唯一のアウト分割取得しているため

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) 

すべてのエクササイズが技術的に関わらず、それを必要とするかどうかのすべてのフィールドを持つことになりますので、これは資源の無駄のように思えますか否か。

次に、サブクラス化はどうですか?それは私があきらめて、自分よりも知識のある人にアピールすることを決めたときです。

このモデルを編成する最も良い方法は何ですか?

答えて

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() 
+1

+1、測定の代わりにワークアウトの一部にするべきではありません。 –

+0

あなたは両方の場所に置くことができますので、トレーニング(またはトレーニング)は複数の日付にまたがることができ、 。 –

+0

しかし、通常は毎日のワークアウト、別々のワークアウトは別々にリストアップする必要があります。それ以外の場合はワークアウトローは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) 

など。どこでもタイプのgeneric Workoutを使用する必要がない場合は、抽象モデルにすることができます。

+0

私はこれを最初に考えましたが、データベースの移行をせずに別のワークアウトに簡単に追加することはできません。あなたは事前にすべてのトレーニングを知っていなければならないでしょう。これは実用的ではないかもしれません。 –

+0

運動の基本タイプ*を事前に知っておく必要がありますが、運動療法の分野が劇的に変化しない限り、好気性/心臓、体重などはあまり多くありません。同じ、または少なくとも一般的に「ワークアウト」よりも似ています。 –

関連する問題