Home > Software design >  Django generic ListView, refering to each items in the object_list
Django generic ListView, refering to each items in the object_list

Time:11-01

I want to know the amount of trainees for each training in the ListView adding a context.

I've search for how to reference each item in the ListView in order to perform a further query on each one.

If anyone know a more efective way, i'll be grateful

class TrainingsView(ListView):
    model = NewHireTraining
    template_name = 'nht/trainings.html'
    context_object_name = 'trainings'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['headcount'] = Trainee.objects.filter(new_hire_training = self.SOMETHING).count()
        return context

Adding NewHireTraining and Trainee models:

class NewHireTraining(models.Model):
    location = models.ForeignKey(Location, on_delete=models.CASCADE)
    program = models.ForeignKey(Program, on_delete=models.CASCADE)
    project = models.ForeignKey(Project, on_delete=models.CASCADE)
    trainer = models.ForeignKey(Trainer, on_delete=models.RESTRICT)
    start_date = models.DateField()
    nesting_date = models.DateField()
    production_date = models.DateField()

    def __str__(self):
        return str(self.program)   ' '   str(self.project)   ' '   str(self.start_date)


class Trainee(models.Model):
    first_name = models.CharField(max_length=55)
    last_name = models.CharField(max_length=55)
    employee_number = models.IntegerField()
    hire_date = models.DateField()
    is_term = models.BooleanField(default=False)
    new_hire_training = models.ForeignKey(NewHireTraining, on_delete=models.CASCADE, default="")

    def __str__(self):
        return self.first_name   ' '   self.last_name

CodePudding user response:

You can annotate the queryset with the number of Trainees:

from django.db.models import Count

class TrainingsView(ListView):
    model = NewHireTraining
    template_name = 'nht/trainings.html'
    context_object_name = 'trainings'
    queryset = NewHireTraining.objects.annotate(headcount=Count('trainee'))

The NewHireTraining objects that arise from this queryset will have an extra attribute .headcount with the total number of related Trainees.

In the template you thus can render this with:

{% for training in trainings %}
    {{ trailing }}: {{ trailing.headcount }}
{% endfor %}
  • Related