Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize the repos API query #5451

Merged
merged 1 commit into from Mar 18, 2019
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 13 additions & 9 deletions readthedocs/oauth/models.py
Expand Up @@ -179,19 +179,23 @@ def clone_fuzzy_url(self):
def matches(self, user):
"""Projects that exist with repository URL already."""
# Support Git scheme GitHub url format that may exist in database
fuzzy_url = self.clone_url.replace('git://', '').replace('.git', '')
projects = (Project
.objects
.public(user)
.filter(Q(repo=self.clone_url) |
Q(repo__iendswith=fuzzy_url) |
Q(repo__iendswith=fuzzy_url + '.git'))) # yapf: disable
truncated_url = self.clone_url.replace('.git', '')
http_url = self.clone_url.replace('git://', 'https://').replace('.git', '')

projects = Project.objects.public(user).filter(
Q(repo=self.clone_url) |
Q(repo=truncated_url) |
Q(repo=truncated_url + '.git') |
Q(repo=http_url) |
Q(repo=http_url + '.git')
).values('slug')

return [{
'id': project.slug,
'id': project['slug'],
'url': reverse(
'projects_detail',
kwargs={
'project_slug': project.slug,
'project_slug': project['slug'],
},
),
} for project in projects]
21 changes: 21 additions & 0 deletions readthedocs/projects/migrations/0041_index-repo-field.py
@@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-03-13 17:03
from __future__ import unicode_literals

from django.db import migrations, models
import readthedocs.projects.validators


class Migration(migrations.Migration):

dependencies = [
('projects', '0040_increase_path_max_length'),
]

operations = [
migrations.AlterField(
model_name='project',
name='repo',
field=models.CharField(db_index=True, help_text='Hosted documentation repository URL', max_length=255, validators=[readthedocs.projects.validators.RepositoryURLValidator()], verbose_name='Repository URL'),
),
]
1 change: 1 addition & 0 deletions readthedocs/projects/models.py
Expand Up @@ -116,6 +116,7 @@ class Project(models.Model):
max_length=255,
validators=[validate_repository_url],
help_text=_('Hosted documentation repository URL'),
db_index=True,
)
repo_type = models.CharField(
_('Repository type'),
Expand Down
2 changes: 2 additions & 0 deletions readthedocs/restapi/serializers.py
Expand Up @@ -173,6 +173,8 @@ class RemoteRepositorySerializer(serializers.ModelSerializer):
"""Remote service repository serializer."""

organization = RemoteOrganizationSerializer()

# This field does create an additional query per object returned
matches = serializers.SerializerMethodField()

class Meta:
Expand Down
4 changes: 4 additions & 0 deletions readthedocs/restapi/views/model_views.py
Expand Up @@ -337,6 +337,10 @@ def get_queryset(self):
service.adapter.provider_id for service in registry
],
)

# optimizes for the RemoteOrganizationSerializer
query = query.select_related('organization')

return query


Expand Down