Home > Software design >  Incorrect Context Appearing in Django Project
Incorrect Context Appearing in Django Project

Time:08-26

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)
  • Related