Skip to content

Commit

Permalink
feat: Add AliasContent admin Site filter (#108)
Browse files Browse the repository at this point in the history
  • Loading branch information
Aiky30 authored Apr 12, 2022
1 parent b70e1c1 commit 29a8708
Show file tree
Hide file tree
Showing 7 changed files with 227 additions and 58 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Changelog

Unreleased
==========
* feat: Add AliasContent admin changelist Site filter

1.3.0 (2022-04-12)
==================
Expand Down
4 changes: 2 additions & 2 deletions djangocms_alias/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from .cms_config import AliasCMSConfig
from .constants import USAGE_ALIAS_URL_NAME
from .filters import LanguageFilter
from .filters import LanguageFilter, SiteFilter
from .forms import AliasContentForm
from .models import Alias, AliasContent, Category
from .urls import urlpatterns
Expand Down Expand Up @@ -101,7 +101,7 @@ def delete_model(self, request, obj):
@admin.register(AliasContent)
class AliasContentAdmin(*alias_content_admin_classes):
form = AliasContentForm
list_filter = (LanguageFilter,)
list_filter = (LanguageFilter, SiteFilter)
list_display = alias_content_admin_list_display
# Disable dropdown actions
actions = None
Expand Down
7 changes: 7 additions & 0 deletions djangocms_alias/constants.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
PLUGIN_URL_NAME_PREFIX = 'djangocms_alias'

# Alias Url endpoint names
CREATE_ALIAS_URL_NAME = f'{PLUGIN_URL_NAME_PREFIX}_create'
DELETE_ALIAS_URL_NAME = f'{PLUGIN_URL_NAME_PREFIX}_delete'
DETACH_ALIAS_PLUGIN_URL_NAME = f'{PLUGIN_URL_NAME_PREFIX}_detach_plugin'
Expand All @@ -10,4 +11,10 @@
USAGE_ALIAS_URL_NAME = f'{PLUGIN_URL_NAME_PREFIX}_alias_usage'
LIST_ALIAS_URL_NAME = f'{PLUGIN_URL_NAME_PREFIX}_aliascontent_changelist'

# Static Alias
DEFAULT_STATIC_ALIAS_CATEGORY_NAME = "Static Alias"

# Admin Filters
LANGUAGE_FILTER_URL_PARAM = "language"
SITE_FILTER_URL_PARAM = "site"
SITE_FILTER_NO_SITE_VALUE = "no_site"
49 changes: 47 additions & 2 deletions djangocms_alias/filters.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
from django.contrib import admin
from django.utils.translation import gettext_lazy as _

from cms.forms.utils import get_sites
from cms.utils.i18n import get_language_tuple, get_site_language_from_request

from .constants import (
LANGUAGE_FILTER_URL_PARAM,
SITE_FILTER_NO_SITE_VALUE,
SITE_FILTER_URL_PARAM,
)


class LanguageFilter(admin.SimpleListFilter):
title = _("language")
parameter_name = "language"
title = _("Language")
parameter_name = LANGUAGE_FILTER_URL_PARAM

def lookups(self, request, model_admin):
return get_language_tuple()
Expand All @@ -31,3 +38,41 @@ def choices(self, changelist):
),
"display": title,
}


class SiteFilter(admin.SimpleListFilter):
title = _("Site")
parameter_name = SITE_FILTER_URL_PARAM

def lookups(self, request, model_admin):
return [(site.pk, site.name) for site in get_sites()]

def queryset(self, request, queryset):
chosen_site = self.value()
if chosen_site and chosen_site == SITE_FILTER_NO_SITE_VALUE:
return queryset.filter(alias__site__isnull=True)
elif chosen_site:
return queryset.filter(alias__site__pk=int(chosen_site))
return queryset

def choices(self, changelist):
yield {
"selected": self.value() is None,
"query_string": changelist.get_query_string(remove=[self.parameter_name]),
"display": _("All"),
}
yield {
"selected": self.value() == SITE_FILTER_NO_SITE_VALUE,
"query_string": changelist.get_query_string(
{self.parameter_name: SITE_FILTER_NO_SITE_VALUE}
),
"display": _("No site"),
}
for lookup, title in self.lookup_choices:
yield {
"selected": self.value() == str(lookup),
"query_string": changelist.get_query_string(
{self.parameter_name: lookup}
),
"display": title,
}
4 changes: 2 additions & 2 deletions tests/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,8 @@ def _get_instance_request(self, instance, user, path=None, edit=False,
return request

def _process_request_by_toolbar_middleware(self, request, obj=None):
midleware = ToolbarMiddleware()
midleware.process_request(request)
middleware = ToolbarMiddleware(request)
middleware.process_request(request)
if hasattr(request, 'toolbar'):
if obj:
request.toolbar.set_object(obj)
Expand Down
52 changes: 0 additions & 52 deletions tests/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,58 +11,6 @@
from djangocms_alias.utils import is_versioning_enabled


class FiltersTestCase(CMSTestCase):
def setUp(self):
self.superuser = self.get_superuser()

def test_language_filter(self):
"""
When rendering aliascontent manager language filter
"""
category = Category.objects.create(name='Language Filter Category')
alias = AliasModel.objects.create(
category=category,
position=0,
)
expected_en_content = AliasContent.objects.create(
alias=alias,
name="EN Alias Content",
language="en",
)
expected_de_content = AliasContent.objects.create(
alias=alias,
name="DE Alias Content",
language="de",
)
# If versioning is enabled be sure to create a version
if is_versioning_enabled():
from djangocms_versioning.models import Version

Version.objects.create(content=expected_en_content, created_by=self.superuser)
Version.objects.create(content=expected_de_content, created_by=self.superuser)

base_url = self.get_admin_url(AliasContent, "changelist")

with self.login_user_context(self.superuser):
# en is the default language configured for the site
response_default = self.client.get(base_url)
qs_default = response_default.context["cl"].queryset
# en should have a result
response_en = self.client.get(base_url + "?language=en")
qs_en = response_en.context["cl"].queryset
# de should have a result
response_de = self.client.get(base_url + "?language=de")
qs_de = response_de.context["cl"].queryset
# fr should have no result and be empty because nothing was created
response_fr = self.client.get(base_url + "?language=fr")
qs_fr = response_fr.context["cl"].queryset

self.assertEqual(set(qs_default), set([expected_en_content]))
self.assertEqual(set(qs_en), set([expected_en_content]))
self.assertEqual(set(qs_de), set([expected_de_content]))
self.assertEqual(set(qs_fr), set([]))


class AliasContentManagerTestCase(CMSTestCase):
def setUp(self):
self.superuser = self.get_superuser()
Expand Down
168 changes: 168 additions & 0 deletions tests/test_admin_filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
from django.contrib.sites.models import Site

from cms.utils import get_current_site

from djangocms_alias.constants import (
SITE_FILTER_NO_SITE_VALUE,
SITE_FILTER_URL_PARAM,
)
from djangocms_alias.models import Alias as AliasModel, AliasContent, Category
from djangocms_alias.utils import is_versioning_enabled

from .base import BaseAliasPluginTestCase


class LanguageFiltersTestCase(BaseAliasPluginTestCase):

def test_language_filter(self):
"""
When rendering aliascontent manager language filter changing the language
should filter the results.
"""
category = Category.objects.create(name='Language Filter Category')
alias = AliasModel.objects.create(
category=category,
position=0,
)
expected_en_content = AliasContent.objects.create(
alias=alias,
name="EN Alias Content",
language="en",
)
expected_de_content = AliasContent.objects.create(
alias=alias,
name="DE Alias Content",
language="de",
)
# If versioning is enabled be sure to create a version
if is_versioning_enabled():
from djangocms_versioning.models import Version

Version.objects.create(content=expected_en_content, created_by=self.superuser)
Version.objects.create(content=expected_de_content, created_by=self.superuser)

base_url = self.get_admin_url(AliasContent, "changelist")

with self.login_user_context(self.superuser):
# en is the default language configured for the site
response_default = self.client.get(base_url)
# en should have a result
response_en = self.client.get(base_url + "?language=en")
# de should have a result
response_de = self.client.get(base_url + "?language=de")
# fr should have no result and be empty because nothing was created
response_fr = self.client.get(base_url + "?language=fr")

self.assertEqual(
set(response_default.context["cl"].queryset),
set([expected_en_content])
)
self.assertEqual(
set(response_en.context["cl"].queryset),
set([expected_en_content])
)
self.assertEqual(
set(response_de.context["cl"].queryset),
set([expected_de_content])
)
self.assertEqual(
set(response_fr.context["cl"].queryset),
set([])
)


class SiteFiltersTestCase(BaseAliasPluginTestCase):

def test_site_filter(self):
"""
When rendering aliascontent manager site filter changing the site
should filter the results.
"""
current_site = get_current_site()
another_site = Site.objects.create(
name="Other site",
domain="othersite.here"
)
empty_site = Site.objects.create(
name="Empty site",
domain="emptysite.here"
)
category = Category.objects.create(name='Site Filter Category')
current_site_alias = AliasModel.objects.create(
category=category,
site=current_site,
)
current_site_alias_content = AliasContent.objects.create(
alias=current_site_alias,
name="Current Site Alias Content",
language="en",
)
another_site_alias = AliasModel.objects.create(
category=category,
site=another_site,
)
another_site_alias_content = AliasContent.objects.create(
alias=another_site_alias,
name="Another Site Alias Content",
language="en",
)
no_site_alias = AliasModel.objects.create(
category=category,
)
no_site_alias_content = AliasContent.objects.create(
alias=no_site_alias,
name="No Site Alias Content",
language="en",
)

# If versioning is enabled be sure to create a version
if is_versioning_enabled():
from djangocms_versioning.models import Version

Version.objects.create(content=current_site_alias_content, created_by=self.superuser)
Version.objects.create(content=another_site_alias_content, created_by=self.superuser)
Version.objects.create(content=no_site_alias_content, created_by=self.superuser)

base_url = self.get_admin_url(AliasContent, "changelist")

with self.login_user_context(self.superuser):
# en is the default language configured for the site
response_default = self.client.get(base_url)
# filter by aliases with the current site
response_current_site = self.client.get(f"{base_url}?{SITE_FILTER_URL_PARAM}={current_site.pk}")
# filter by aliases with a different site set
response_other_site = self.client.get(f"{base_url}?{SITE_FILTER_URL_PARAM}={another_site.pk}")
# filter by aliases with an empty site set
response_empty_site = self.client.get(f"{base_url}?{SITE_FILTER_URL_PARAM}={empty_site.pk}")
# filter by aliases with no site set
response_no_site = self.client.get(f"{base_url}?{SITE_FILTER_URL_PARAM}={SITE_FILTER_NO_SITE_VALUE}")

# By default all alias are shown
self.assertEqual(
set(response_default.context["cl"].queryset),
set([
current_site_alias_content,
another_site_alias_content,
no_site_alias_content,
])
)
# Only alias attached to the current site are shown when filtered by the current site
self.assertEqual(
set(response_current_site.context["cl"].queryset),
set([current_site_alias_content])
)
# Only alias attached to the current site are shown when filtered by another site
self.assertEqual(
set(response_other_site.context["cl"].queryset),
set([another_site_alias_content])
)
# Only alias attached to the current site are shown when filtered by no site
self.assertEqual(
set(response_no_site.context["cl"].queryset),
set([no_site_alias_content])
)
# No are shown when filtered by an empty site
self.assertEqual(
set(response_empty_site.context["cl"].queryset),
set([])
)

0 comments on commit 29a8708

Please sign in to comment.