|
6 | 6 | import structlog
|
7 | 7 | from django.conf import settings
|
8 | 8 | from django.contrib.auth.models import AnonymousUser
|
| 9 | +from django.db.models import Q |
9 | 10 | from django.http import Http404
|
10 | 11 | from django.http import JsonResponse
|
11 | 12 | from django.shortcuts import get_object_or_404
|
@@ -341,7 +342,6 @@ def _v1(self, project, version, build, filename, url, request):
|
341 | 342 | resolver = Resolver()
|
342 | 343 | versions_active_built_not_hidden = Version.objects.none()
|
343 | 344 | sorted_versions_active_built_not_hidden = Version.objects.none()
|
344 |
| - user = request.user |
345 | 345 |
|
346 | 346 | versions_active_built_not_hidden = (
|
347 | 347 | self._get_versions(request, project).select_related("project").order_by("-slug")
|
@@ -380,37 +380,11 @@ def _v1(self, project, version, build, filename, url, request):
|
380 | 380 | project.addons.flyout_sorting_latest_stable_at_beginning,
|
381 | 381 | )
|
382 | 382 |
|
383 |
| - main_project = project.main_language_project or project |
384 |
| - |
385 |
| - # Exclude the current project since we don't want to return itself as a translation |
386 |
| - project_translations = ( |
387 |
| - Project.objects.public(user=user) |
388 |
| - .filter(pk__in=main_project.translations.all()) |
389 |
| - .exclude(slug=project.slug) |
390 |
| - ) |
391 |
| - |
392 |
| - # Include main project as translation if the current project is one of the translations |
393 |
| - if project != main_project: |
394 |
| - project_translations |= Project.objects.public(user=user).filter(slug=main_project.slug) |
395 |
| - project_translations = project_translations.order_by("language").select_related( |
396 |
| - "main_language_project" |
397 |
| - ) |
398 |
| - |
399 | 383 | data = {
|
400 | 384 | "api_version": "1",
|
401 |
| - "projects": { |
402 |
| - "current": ProjectSerializerNoLinks( |
403 |
| - project, |
404 |
| - resolver=resolver, |
405 |
| - version_slug=version.slug if version else None, |
406 |
| - ).data, |
407 |
| - "translations": ProjectSerializerNoLinks( |
408 |
| - project_translations, |
409 |
| - resolver=resolver, |
410 |
| - version_slug=version.slug if version else None, |
411 |
| - many=True, |
412 |
| - ).data, |
413 |
| - }, |
| 385 | + "projects": self._get_projects_response( |
| 386 | + request=request, project=project, version=version, resolver=resolver |
| 387 | + ), |
414 | 388 | "versions": {
|
415 | 389 | "current": VersionSerializerNoLinks(
|
416 | 390 | version,
|
@@ -617,6 +591,46 @@ def _v1(self, project, version, build, filename, url, request):
|
617 | 591 |
|
618 | 592 | return data
|
619 | 593 |
|
| 594 | + def _get_projects_response(self, *, request, project, version, resolver): |
| 595 | + main_project = project.main_language_project or project |
| 596 | + |
| 597 | + translation_filter = Q(pk__in=main_project.translations.all()) |
| 598 | + # Include main project as translation if the current project is one of the translations |
| 599 | + if main_project != project: |
| 600 | + translation_filter |= Q(pk=main_project.pk) |
| 601 | + |
| 602 | + translations_qs = ( |
| 603 | + Project.objects.public(user=request.user) |
| 604 | + .filter(translation_filter) |
| 605 | + # Exclude the current project since we don't want to return itself as a translation |
| 606 | + .exclude(pk=project.pk) |
| 607 | + .order_by("language") |
| 608 | + .select_related("main_language_project") |
| 609 | + .prefetch_related("tags", "domains", "related_projects", "users") |
| 610 | + ) |
| 611 | + # NOTE: we check if there are translations first, |
| 612 | + # otherwise evaluating the queryset will be more expensive |
| 613 | + # even if there are no results. Django optimizes the queryset |
| 614 | + # if only we need to check if there are results or not. |
| 615 | + if translations_qs.exists(): |
| 616 | + translations = ProjectSerializerNoLinks( |
| 617 | + translations_qs, |
| 618 | + resolver=resolver, |
| 619 | + version_slug=version.slug if version else None, |
| 620 | + many=True, |
| 621 | + ).data |
| 622 | + else: |
| 623 | + translations = [] |
| 624 | + |
| 625 | + return { |
| 626 | + "current": ProjectSerializerNoLinks( |
| 627 | + project, |
| 628 | + resolver=resolver, |
| 629 | + version_slug=version.slug if version else None, |
| 630 | + ).data, |
| 631 | + "translations": translations, |
| 632 | + } |
| 633 | + |
620 | 634 | def _get_filetreediff_response(self, *, request, project, version, resolver):
|
621 | 635 | """
|
622 | 636 | Get the file tree diff response for the given version.
|
|
0 commit comments