Merge pull request #332 from nephila/feature/improve_admin

Improve admin filtering
This commit is contained in:
Iacopo Spalletti 2016-09-19 22:39:39 +02:00 committed by GitHub
commit 68dede34b2
6 changed files with 96 additions and 4 deletions

View file

@ -19,6 +19,7 @@ History
* Added plugins templateset.
* Improved category admin to avoid circular relationships.
* Dropped strict dependency on aldryn-search, haystack. Install separately for search support.
* Improved admin filtering.
******************
0.8.9 (unreleased)

View file

@ -5,7 +5,7 @@ from copy import deepcopy
from aldryn_apphooks_config.admin import BaseAppHookConfig, ModelAppHookConfig
from cms.admin.placeholderadmin import FrontendEditableAdminMixin, PlaceholderAdminMixin
from cms.models import CMSPlugin
from cms.models import CMSPlugin, ValidationError
from django import forms
from django.apps import apps
from django.conf import settings
@ -14,7 +14,7 @@ from django.contrib import admin
from django.contrib.sites.models import Site
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.utils.six import callable
from django.utils.six import callable, text_type
from django.utils.translation import get_language_from_request, ugettext_lazy as _
from parler.admin import TranslatableAdmin
@ -30,6 +30,30 @@ except ImportError:
pass
class SiteListFilter(admin.SimpleListFilter):
title = _('site')
parameter_name = 'sites'
def lookups(self, request, model_admin):
restricted_sites = model_admin.get_restricted_sites(request).values_list('id', flat=True)
qs = Site.objects.all()
if restricted_sites:
qs = qs.filter(id__in=restricted_sites)
return [(site.id, text_type(site.name)) for site in qs]
def queryset(self, request, queryset):
try:
if 'sites' in self.used_parameters:
return queryset.on_site(Site.objects.get(pk=self.used_parameters['sites']))
return queryset
except Site.DoesNotExist as e: # pragma: no cover
raise admin.options.IncorrectLookupParameters(e)
except ValidationError as e: # pragma: no cover
raise admin.options.IncorrectLookupParameters(e)
class BlogCategoryAdmin(EnhancedModelAdminMixin, ModelAppHookConfig, TranslatableAdmin):
form = CategoryAdminForm
list_display = [
@ -55,7 +79,7 @@ class PostAdmin(PlaceholderAdminMixin, FrontendEditableAdminMixin,
'title', 'author', 'date_published', 'app_config', 'all_languages_column',
'date_published_end'
]
list_filter = ('app_config',)
search_fields = ('translations__title',)
date_hierarchy = 'date_published'
raw_id_fields = ['author']
frontend_editable_fields = ('title', 'abstract', 'post_text')
@ -85,6 +109,21 @@ class PostAdmin(PlaceholderAdminMixin, FrontendEditableAdminMixin,
}
_sites = None
def get_list_filter(self, request):
filters = ['app_config', 'publish', 'date_published']
if get_setting('MULTISITE'):
filters.append(SiteListFilter)
try:
from taggit_helpers.admin import TaggitListFilter
filters.append(TaggitListFilter)
except ImportError: # pragma: no cover
try:
from taggit_helpers import TaggitListFilter
filters.append(TaggitListFilter)
except ImportError:
pass
return filters
def get_urls(self):
"""
Customize the modeladmin urls

View file

@ -39,6 +39,10 @@ If you want to enable haystack support, in addition to the above:
* configure haystack according to `aldryn-search docs <https://github.com/aldryn/aldryn-search#usage>`_
and `haystack docs <http://django-haystack.readthedocs.io/en/stable/>`_.
To enable taggit filtering support in the admin install djangocms-blog with::
pip install djangocms-blog[taggit]
*********************
Minimal configuration
*********************

View file

@ -11,3 +11,4 @@ wheel
pysolr
django-parler>=1.6
aldryn-search
django-taggit-helpers

View file

@ -42,7 +42,8 @@ setup(
'djangocms-apphook-setup',
],
extras_require={
'search': ['aldryn-search']
'search': ['aldryn-search'],
'taggit-helpers': ['django-taggit-helpers']
},
license='BSD',
zip_safe=False,

View file

@ -90,6 +90,52 @@ class AdminTest(BaseTest):
self.assertEqual(response.status_code, 302)
self.assertEqual(response['Location'], '/')
def test_admin_changelist_view(self):
posts = self.get_posts()
post_admin = admin.site._registry[Post]
request = self.get_page_request('/', self.user, r'/en/blog/', edit=False)
# Normal changelist, all existing posts
response = post_admin.changelist_view(request)
self.assertEqual(response.context_data['cl'].queryset.count(), len(posts))
self.assertTrue(posts[0] in response.context_data['cl'].queryset.all())
# Site 2 is added to first post, but no changelist filter, no changes
posts[0].sites.add(self.site_2)
response = post_admin.changelist_view(request)
self.assertTrue(posts[0] in response.context_data['cl'].queryset.all())
# Filtering on site, first post not shown
request = self.get_page_request('/', self.user, r'/en/blog/?sites=1', edit=False)
response = post_admin.changelist_view(request)
self.assertEqual(response.context_data['cl'].queryset.count(), len(posts) - 1)
self.assertTrue(posts[0] not in response.context_data['cl'].queryset.all())
# Removing site filtering, first post appears again
request = self.get_page_request('/', self.user, r'/en/blog/?', edit=False)
response = post_admin.changelist_view(request)
self.assertEqual(response.context_data['cl'].queryset.count(), len(posts))
self.assertTrue(posts[0] in response.context_data['cl'].queryset.all())
# Filtering on the apphook config and site
request = self.get_page_request('/', self.user, r'/en/blog/?app_config__id__exact=1&sites=1', edit=False)
response = post_admin.changelist_view(request)
# First and last post in the list are now in the queryset
self.assertEqual(response.context_data['cl'].queryset.count(), len(posts) - 2)
self.assertTrue(posts[0] not in response.context_data['cl'].queryset.all())
self.assertTrue(posts[-1] not in response.context_data['cl'].queryset.all())
# Publishing one post, two published in total
posts[1].publish = True
posts[1].save()
published = Post.objects.published(current_site=False)
request = self.get_page_request('/', self.user, r'/en/blog/?publish__exact=1', edit=False)
response = post_admin.changelist_view(request)
# The admin queryset and the model queryset are the same
self.assertEqual(response.context_data['cl'].queryset.count(), published.count())
# Published post is in the changelist queryset
self.assertTrue(posts[1] in response.context_data['cl'].queryset.all())
def test_admin_blogconfig_views(self):
post_admin = admin.site._registry[BlogConfig]
request = self.get_page_request('/', self.user, r'/en/blog/', edit=False)