|
1 | 1 | """Project model QuerySet classes."""
|
2 | 2 |
|
3 | 3 | from django.db import models
|
4 |
| -from django.db.models import Q |
| 4 | +from django.db.models import Q, OuterRef, Subquery, Prefetch |
5 | 5 | from guardian.shortcuts import get_objects_for_user
|
6 | 6 |
|
7 | 7 | from readthedocs.core.utils.extend import SettingsOverrideObject
|
@@ -75,10 +75,32 @@ def is_active(self, project):
|
75 | 75 |
|
76 | 76 | return True
|
77 | 77 |
|
| 78 | + def prefetch_latest_build(self): |
| 79 | + """ |
| 80 | + For a given queryset of projects, prefetch the latest build for each project |
| 81 | +
|
| 82 | + This should come after any filtering. |
| 83 | + """ |
| 84 | + from readthedocs.builds.models import Build |
| 85 | + |
| 86 | + # Prefetch the latest build for each project. |
| 87 | + subquery = Subquery( |
| 88 | + Build.objects.filter( |
| 89 | + project=OuterRef('project_id') |
| 90 | + ).order_by('-date').values_list('id', flat=True)[:1] |
| 91 | + ) |
| 92 | + latest_build = Prefetch( |
| 93 | + 'builds', |
| 94 | + Build.objects.filter(pk__in=subquery), |
| 95 | + to_attr=self.model.LATEST_BUILD_CACHE, |
| 96 | + ) |
| 97 | + return self.prefetch_related(latest_build) |
| 98 | + |
78 | 99 | # Aliases
|
79 | 100 |
|
80 | 101 | def dashboard(self, user=None):
|
81 |
| - return self.for_admin_user(user) |
| 102 | + """Get the projects for this user including the latest build""" |
| 103 | + return self.for_admin_user(user).prefetch_latest_build() |
82 | 104 |
|
83 | 105 | def api(self, user=None, detail=True):
|
84 | 106 | if detail:
|
|
0 commit comments