Querying from child of model given django inheritance and m2m link to parent

与世无争的帅哥 提交于 2019-12-25 14:08:21

问题


Among my models, I have Exercise which has a m2m link to Workout. I also have WorkoutPlan and LogBook which are types of Workouts. WorkoutPlan is where ideal workouts are stored. LogBook is where a user stores the workout they actually completed. They can also link a LogBook to a WorkoutPlan to indicate that the actual performance was connected to an original ideal plan.

class Exercise(NameDescModel):
    muscles = models.ManyToManyField(Muscle, blank=True)
    groups = models.ManyToManyField(Group, blank=True)
    priority_score = models.DecimalField(max_digits=5, decimal_places=3, editable=False, default = 0)
    frequency = models.IntegerField()
    time_period = models.CharField(max_length=2, choices=TIME_PERIOD_CHOICES,default=WEEK)
    last_p_calc_date = models.DateField("Date of Last Priority Recalculation", blank=True, null=True, default=datetime.now)

class Workout(NameDescModel):
    exericises = models.ManyToManyField(Exercise, through='Measurement')

class WorkoutPlan(Workout):

    priority_score = models.DecimalField(max_digits=5, decimal_places=3, editable=False, default = 0)
    frequency = models.IntegerField()
    time_period = models.CharField(max_length=2, choices=TIME_PERIOD_CHOICES,default=WEEK)
    time_estimate = models.IntegerField()
    last_p_calc_date = models.DateField("Date of Last Priority Recalculation", blank=True, null=True, default=datetime.now)

class LogBook(Workout):
    workout_date = models.DateField(default=datetime.now)
    notes = models.TextField(blank=True)

    workout_plan = models.ForeignKey(WorkoutPlan, blank=True, null=True)

For a given exercise, I want to pull all of the WorkoutPlans that the exercise is in.

exercise_list = Exercise.objects.order_by('-last_p_calc_date')

for exercise in exercise_list:
    print exercise
    workout_list = []
    for workout in exercise.workout_set.all():
        workout_list.append(workout)
    print list(set(workout_list))
    print ""

I'm realizing that the list of workouts include both WorkoutPlans and LogBooks because exercise is attached to Workout, not to WorkoutPlans or LogBooks specifically.

How might I pull Workouts that are affiliated only to WorkoutPlans?


回答1:


I think you've over-used inheritance here.

I guess you wanted to put the exercises field into a base model because WorkoutPlan and LogBook both have that field. But it seems like in reality WorkoutPlan and LogBook are different types of thing, rather than sub-types of Workout.

Possibly don't you need the exercises field on the LogBook model at all, since it has a foreign key to WorkoutPlan which seems a sensible place to record the exercises... unless you want to record the difference between the plan and exercises actually performed?

I would model it like this:

class Exercise(NameDescModel):
    muscles = models.ManyToManyField(Muscle, blank=True)
    groups = models.ManyToManyField(Group, blank=True)
    priority_score = models.DecimalField(max_digits=5, decimal_places=3, editable=False, default = 0)
    frequency = models.IntegerField()
    time_period = models.CharField(max_length=2, choices=TIME_PERIOD_CHOICES,default=WEEK)
    last_p_calc_date = models.DateField("Date of Last Priority Recalculation", blank=True, null=True, default=datetime.now)

class WorkoutPlan(Workout):
    exercises = models.ManyToManyField(Exercise, through='Measurement')
    priority_score = models.DecimalField(max_digits=5, decimal_places=3, editable=False, default = 0)
    frequency = models.IntegerField()
    time_period = models.CharField(max_length=2, choices=TIME_PERIOD_CHOICES,default=WEEK)
    time_estimate = models.IntegerField()
    last_p_calc_date = models.DateField("Date of Last Priority Recalculation", blank=True, null=True, default=datetime.now)

class LogBook(Workout):
    exercises = models.ManyToManyField(Exercise, through='Measurement')
    workout_date = models.DateField(default=datetime.now)
    notes = models.TextField(blank=True)
    workout_plan = models.ForeignKey(WorkoutPlan, blank=True, null=True)

You can then query either WorkoutPlans or LogBooks from an Exercise instance:

exercise_list = Exercise.objects.order_by('-last_p_calc_date')

for exercise in exercise_list:
    print exercise
    workout_list = exercise.workoutplan_set.all()
    print ""


来源:https://stackoverflow.com/questions/33239601/querying-from-child-of-model-given-django-inheritance-and-m2m-link-to-parent

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!