Skip to content
Open
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
24 changes: 15 additions & 9 deletions readthedocs/projects/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@
from django.db.models import Count
from django.db.models import F
from django.db.models import Max
from django.db.models import Q
from django.utils.translation import gettext_lazy as _
from django_filters import CharFilter
from django_filters import ChoiceFilter
from django_filters import OrderingFilter

Expand Down Expand Up @@ -261,12 +259,20 @@ class RedirectListFilterSet(ModelFilterSet):
empty_label=_("All types"),
)

# Matches against either end of the redirect in a single field so the UI
# stays a single input.
url = CharFilter(
label=_("URL contains"),
method="filter_url_contains",
url = FilteredModelChoiceFilter(
label=_("URL"),
empty_label=_("All URLs"),
to_field_name="from_url",
queryset_method="get_redirect_queryset",
method="get_redirect",
label_attribute="from_url",
)

def filter_url_contains(self, queryset, field_name, value):
return queryset.filter(Q(from_url__icontains=value) | Q(to_url__icontains=value))
def get_redirect_queryset(self):
# Scope choices to the project's redirects passed in at instantiation;
# otherwise the dropdown would show every Redirect across all projects.
# Exclude redirects without a ``from_url`` (eg. clean URL <-> HTML types).
return self.queryset.exclude(from_url="")

def get_redirect(self, queryset, field_name, redirect):
return queryset.filter(from_url=redirect.from_url)
10 changes: 4 additions & 6 deletions readthedocs/redirects/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ def test_list_redirect_filter_by_type(self):
assert len(resp.context["redirects"]) == 1
assert resp.context["redirects"][0].redirect_type == PAGE_REDIRECT

def test_list_redirect_filter_by_url_contains(self):
get(
def test_list_redirect_filter_by_url(self):
other = get(
Redirect,
project=self.project,
redirect_type=PAGE_REDIRECT,
Expand All @@ -108,13 +108,11 @@ def test_list_redirect_filter_by_url_contains(self):
)
resp = self.client.get(
reverse("projects_redirects", args=[self.project.slug]),
{"url": "configuration"},
{"url": other.from_url},
)
assert resp.status_code == 200
pks = {r.pk for r in resp.context["redirects"]}
assert len(pks) == 1
# Matches on the ``to_url`` substring only.
assert self.redirect.pk not in pks
assert pks == {other.pk}

def test_get_redirect(self):
resp = self.client.get(
Expand Down