I am creating a workout project where for every workout there is a list of exercises and for every exercise there is a list of sets which has specific weights and reps.
Here is the model for more clarification:
class Workout(models.Model):
name = models.CharField(max_length = 30,blank=True, null=True)
date = models.DateField(blank=True, null=True)
def __str__(self):
return str(self.date) ' ' self.name
class Exercise(models.Model):
training = models.ForeignKey(Workout, on_delete=models.CASCADE, related_name='exercises',blank=True, null=True)
name = models.CharField(max_length = 30, blank=True, null=True)
def __str__(self):
return self.name
class Set(models.Model):
exercise = models.ForeignKey(Exercise, on_delete=models.CASCADE, related_name='sets',blank=True, null=True)
weight = models.FloatField(validators=[MinValueValidator(0)],blank=True, null=True)
repetitions = models.IntegerField(validators=[MinValueValidator(1)],blank=True, null=True)
order = models.IntegerField(validators=[MinValueValidator(1)],blank=True, null=True)
def __str__(self):
return self.exercise.name ' set #' str(self.order)
I am trying to show the list of rep in each set for a specific excercise in the template page but I keep getting errors such as:
activity() missing 1 required positional argument: 'request'
or even nothing is showing at all. The most recent view I coded shows all the sets for all the excercises which is not the objective.
Here is the views:
def activity(self,request, **kwargs):
template_name = 'my_gym/start_workout.html'
excercises = Exercise.objects.all().order_by('id')
sets = Set.objects.filter(
set=self.object).order_by('id')
context = {
'excercises': excercises,
'sets': sets,
}
return render(request, template_name, context)
I also tried:
def activity(request):
template_name = 'my_gym/start_workout.html'
excercises = Exercise.objects.all().order_by('id')
sets = Set.objects.all().order_by('id')
context = {
'excercises': excercises,
'sets': sets,
}
return render(request, template_name, context)
Here is also another trial using filter:
def activity(request):
template_name = 'my_gym/start_workout.html'
excercises = Exercise.objects.all().order_by('id')
sets = Set.objects.filter(sets=set.excercises).order_by('id')
context = {
'excercises': excercises,
'sets': sets,
}
return render(request, template_name, context)
I got this error:
type object 'set' has no attribute 'excercises'
Here is the template:
{% for set in sets %}
<td>{{set.order}}</td>
<td>{{set.repetitions}}</td>
{% endfor %}
My question is how to show the sets only for the selected excercise.
A more info there is a previous page which shows all th excercises and when one specific exercise is selected I am expecting to see the reps related to this specific excercise only not the reps for all the exercises in the database.
Thank you
CodePudding user response:
As I did in my project(it was blog):
In urls.py
I created new page with category_id(=Category primary key) like this:
path('category/<int:category_id>/', get_category, name='category')
Now in get_category
function I get additional parameter that meant the pk
of the category to which it belongs. And in views.py:
def get_category(request, category_id):
records = Recordings.objects.filter(category=category_id)
category = Category.objects.get(pk=category_id)
context = {
'records': records,
'category': category,
'title': category.title,
}
return render(request=request, template_name='blog/category.html', context=context)
I just filtered them by category.pk and it worked fine In your case Recording = Set, Category = Exercise, category_id = exercise_id
Or if you use another way of creating pages for exercised - pls comment, it will be interesting to find a solution for such a model
P.S. This is early version of my project, there should be used select_related
for request optimizing
P.P.S Optimized version of view urls
# urls.py
path('category/<int:category_id>/', RecordingsByCategory.as_view(), name='category')
# views.py
class RecordingsByCategory(ListView):
model = Recordings
template_name = 'blog/category.html'
context_object_name = 'records'
def get_context_data(self, *, object_list=None, **kwargs):
context = super().get_context_data(**kwargs)
context['title'] = Category.objects.get(pk=self.kwargs['category_id'])
return context
def get_queryset(self):
# kwargs goes from urls.py
return Recordings.objects.select_related('category').filter(category=self.kwargs['category_id'], is_published=True)