Issue
I am building up a workout progress application for a learning project. When setting the class model for the project I came across to schools of thought and I don't know what is the advantages and disadvantages for reach.
Here is the simply version:
class Exercise(models.Model):
name = models.CharField(max_length = 30)
def __str__(self):
return self.name
class Set(models.Model):
exercise = models.ForeignKey(Exercise, on_delete=models.CASCADE, related_name='sets')
weight = models.FloatField(validators=[MinValueValidator(0)])
repetitions = models.IntegerField(validators=[MinValueValidator(1)])
def __str__(self):
return self.exercise.name + ' set #' + str(self.pk)
and the second more complicated is:
class Exercise(models.Model):
# Attributes
name = models.CharField(null=False, blank=False, max_length=100)
# Methods
def __str__(self):
return self.name
class ExerciseSet(models.Model):
# Attributes for exercise sets
exercise = models.ForeignKey(Exercise, null=False, blank=False, on_delete=models.CASCADE)
sets = models.ManyToManyField("my_gym.Set", related_name="sets")
number_of_sets = models.IntegerField(null=False, blank=False, default=3)
# Methods
def __str__(self):
return str(self.exercise.name) + " - " + str(self.number_of_sets) + " sets"
class Set(models.Model):
# Attributes
reps = models.PositiveIntegerField(null=False, blank=False, default=0)
weight = models.DecimalField(max_digits=5, decimal_places=2)
# Methods
def __str__(self):
return (
str(self.reps)
+ " "
+ " x "
+ str(self.weight)
+ " "
)
The requested project outcome is to just to set the progress of the workout logging the weight and reps of each excercise.
My question is which is the more preferred and why should each model be used?
Solution
Your first example is a 1:n (I read it 1 to n) relationship
(exercise) 1 <-> n (sets)
Every Exercise
instance can be associated with an arbitrary number of Set
instances. But Every set is associated with exactly 1 instance of Exercise
.
As I understood your requirements that will totally do the job.
Your second example is a bit complicated, so I will try to break it down.
(exercise) 1 <-> n (exerciseset) <-> n (sets)
Every Exercise
instance can be associated with an arbitrary number of ExerciseSet
instances. But Every ExerciseSet
is associated with exactly 1 instance of Exercise
(all via the .exercise
variable of ExerciseSet
.
Furthermore each ExerciseSet
can be connected to an arbitrary amount of Set
s while each Set
can also be part of multiple (n:n) ExerciseSet.
Since this is a rather complicated structure I am sure what you tried to achieve was an n:n relation ship with a through model.
(exercises) n <-> n (sets)
Now this allows every Exercise to have multiple sets while each set can be part of an arbitrary amount of exercises. This can be achieved by the simple use of a ManyToManyField
on any of the models.
The way how the ManyToMany or n:n relation works is by creating a third table which has a column for each model saving the primary keys, such that each row in that table stores the connection of one exercise and one set. This table is hidden.
Now, it is possible to add the through
param to the ManyToManyField
. This allows to explicitly set that table using a through model, aka intermediary model, see documentation. This model allows you to not only connect both models but add additional information.
I.e. it would be possible to not only let Exercise
s have an arbitrary amount of Set
s, but you could also store the information on how often (some count) that particular set is part of that exercise, or how much time there is for that particular set (without creating a new set), such that the set itself (n:n) can be part of multiple Exercises in different setups, without creating new sets all the time... just writing thoughts here.
The best example for n:n is still the Club
<-> User
relation, where the intermediate model Membership
helps to store which User is in which Club, since a User can be in multiple Clubs and a Club can have multiple User. The Membership could additionally store the information when the user joined the club, or what grade the membership is.
Answered By - coderiot
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.