Wednesday, 30 August 2023

Prefetching related objects for templates

I have two models, Signup and Report, related via a third model, Training:

class Signup(models.Model):
    pilot = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="signups"
    )
    training = models.ForeignKey(
        Training, on_delete=models.CASCADE, related_name="signups"
    )

class Report(models.Model):
    training = models.OneToOneField(
        "trainings.Training", on_delete=models.CASCADE, primary_key=True
    )

And e.g. in the update view for a Report I try to prefetch the Signups and their Pilots and sort them into the context:

class ReportUpdateView(generic.UpdateView):
    model = Report

    def get_object(self):
        training = get_object_or_404(Training, date=self.kwargs["date"])
        report = get_object_or_404(
            Report.objects.select_related("training")
            .prefetch_related("training__signups__pilot")
            training=training,
        )
        return report

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        ...
        runs_by_signup = {}
        for signup in self.object.training.selected_signups:
            runs_by_signup[signup] = [...]
        context["runs_by_signup"] = runs_by_signup
        return context

and in the corresponding template I call signup.pilot like so:


However, each signup.pilot results in a call to the database to figure out the corresponding pilot. Is there a way to avoid these extra calls or do I have to store all information in get_context_data?



from Prefetching related objects for templates

No comments:

Post a Comment