Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions documentcloud/addons/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,19 @@ def __init__(self, *args, **kwargs):

@extend_schema_field(serializers.BooleanField())
def get_active(self, obj):

if hasattr(obj, "active"):
# pre calculate active for efficiency
return obj.active

request = self.context.get("request")
if not request:
return False

return request.user.active_addons.filter(pk=obj.pk).exists()
if not hasattr(self, "_active_pks"):
# build the pinned-addon PK set once per serializer (one query for the page)
# instead of an EXISTS per addon.
self._active_pks = set(
request.user.active_addons.values_list("pk", flat=True)
)
return obj.pk in self._active_pks

class Meta:
model = AddOn
Expand Down
17 changes: 17 additions & 0 deletions documentcloud/addons/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,23 @@ def test_filter_domain_no_partial_host_match(self, client):
assert response.status_code == status.HTTP_200_OK
assert response.json()["results"] == []

def test_list_expand_query_count(self, client, django_assert_num_queries):
"""
Expanding addon+event must not scale queries with the number of runs.
Query count stays flat (the run's addon/github_account/event are
select_related'd and get_active reads a cached PK set).
"""
user = UserFactory(is_staff=True)
client.force_authenticate(user=user)
url = "/api/addon_runs/?expand=addon,event&per_page=100"

for expected_count in range(1, 11):
AddOnRunFactory(user=user, addon=AddOnFactory())
with django_assert_num_queries(7):
response = client.get(url)
assert response.status_code == status.HTTP_200_OK
assert len(response.json()["results"]) == expected_count


@pytest.mark.django_db()
class TestAddOnEventAPI:
Expand Down
2 changes: 1 addition & 1 deletion documentcloud/addons/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,7 @@ def get_queryset(self):
"""Only fetch add-on runs viewable to this user"""
queryset = AddOnRun.objects.get_viewable(self.request.user)
if is_expanded(self.request, "addon"):
queryset = queryset.select_related("addon")
queryset = queryset.select_related("addon", "addon__github_account")
if is_expanded(self.request, "event"):
queryset = queryset.select_related("event")
return queryset
Expand Down
Loading