From 88c7640ad16fa26f18c8988ff48323b99d4e25aa Mon Sep 17 00:00:00 2001 From: Anthony Johnson Date: Tue, 3 Dec 2019 14:50:28 -0700 Subject: [PATCH 1/2] Partial revert of 81768fc7 (#6398) This queryset introduced a bug where a from_url of 5 characters would produce and exception. --- readthedocs/redirects/querysets.py | 78 +----------------------------- 1 file changed, 2 insertions(+), 76 deletions(-) diff --git a/readthedocs/redirects/querysets.py b/readthedocs/redirects/querysets.py index b549e250daf..eb3f9141d51 100644 --- a/readthedocs/redirects/querysets.py +++ b/readthedocs/redirects/querysets.py @@ -1,8 +1,6 @@ """Queryset for the redirects app.""" from django.db import models -from django.db.models import Value, CharField, IntegerField, Q, F, ExpressionWrapper -from django.db.models.functions import Substr, Length from readthedocs.core.utils.extend import SettingsOverrideObject @@ -26,80 +24,8 @@ def api(self, user=None, detail=True): queryset = self._add_user_repos(queryset, user) return queryset - def get_redirect_path_with_status(self, path, full_path=None, language=None, version_slug=None): - # add extra fields with the ``path`` and ``full_path`` to perform a - # filter at db level instead with Python - queryset = self.annotate( - path=Value( - path, - output_field=CharField(), - ), - full_path=Value( - full_path, - output_field=CharField(), - ), - - from_url_length=ExpressionWrapper( - Length('from_url'), - output_field=IntegerField(), - ), - - # 1-indexed - from_url_without_rest=Substr( - 'from_url', - 1, - F('from_url_length') - 5, # Strip "$rest" - output_field=CharField(), - ), - - # 1-indexed - full_path_without_rest=Substr( - 'full_path', - 1, - F('from_url_length') - 5, # Strip "$rest" - output_field=CharField(), - ), - ) - prefix = Q( - redirect_type='prefix', - path__startswith=F('from_url'), - ) - page = Q( - redirect_type='page', - path__iexact=F('from_url'), - ) - exact = ( - Q( - redirect_type='exact', - from_url__endswith='$rest', - # This works around a bug in Django doing a substr and an endswith, - # so instead we do 2 substrs and an exact - # https://code.djangoproject.com/ticket/29155 - full_path_without_rest=F('from_url_without_rest'), - ) | Q( - redirect_type='exact', - full_path__iexact=F('from_url'), - ) - ) - sphinx_html = ( - Q( - redirect_type='sphinx_html', - path__endswith='/', - ) | Q( - redirect_type='sphinx_html', - path__endswith='/index.html', - ) - ) - sphinx_htmldir = Q( - redirect_type='sphinx_htmldir', - path__endswith='.html', - ) - - # There should be one and only one redirect returned by this query. I - # can't think in a case where there can be more at this point. I'm - # leaving the loop just in case for now - queryset = queryset.filter(prefix | page | exact | sphinx_html | sphinx_htmldir) - for redirect in queryset.select_related('project'): + def def get_redirect_path_with_status(self, path, full_path=None, language=None, version_slug=None): + for redirect in self.select_related('project'): new_path = redirect.get_redirect_path( path=path, language=language, From 497024fc81e95ef3aeed1c8b5c25409fa661dd14 Mon Sep 17 00:00:00 2001 From: Anthony Johnson Date: Tue, 3 Dec 2019 14:58:34 -0700 Subject: [PATCH 2/2] Fix typo --- readthedocs/redirects/querysets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readthedocs/redirects/querysets.py b/readthedocs/redirects/querysets.py index eb3f9141d51..1d7fb15e7fe 100644 --- a/readthedocs/redirects/querysets.py +++ b/readthedocs/redirects/querysets.py @@ -24,7 +24,7 @@ def api(self, user=None, detail=True): queryset = self._add_user_repos(queryset, user) return queryset - def def get_redirect_path_with_status(self, path, full_path=None, language=None, version_slug=None): + def get_redirect_path_with_status(self, path, full_path=None, language=None, version_slug=None): for redirect in self.select_related('project'): new_path = redirect.get_redirect_path( path=path,