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. * Added plugins templateset.
* Improved category admin to avoid circular relationships. * Improved category admin to avoid circular relationships.
* Dropped strict dependency on aldryn-search, haystack. Install separately for search support. * Dropped strict dependency on aldryn-search, haystack. Install separately for search support.
* Improved admin filtering.
****************** ******************
0.8.9 (unreleased) 0.8.9 (unreleased)

View file

@ -5,7 +5,7 @@ from copy import deepcopy
from aldryn_apphooks_config.admin import BaseAppHookConfig, ModelAppHookConfig from aldryn_apphooks_config.admin import BaseAppHookConfig, ModelAppHookConfig
from cms.admin.placeholderadmin import FrontendEditableAdminMixin, PlaceholderAdminMixin from cms.admin.placeholderadmin import FrontendEditableAdminMixin, PlaceholderAdminMixin
from cms.models import CMSPlugin from cms.models import CMSPlugin, ValidationError
from django import forms from django import forms
from django.apps import apps from django.apps import apps
from django.conf import settings from django.conf import settings
@ -14,7 +14,7 @@ from django.contrib import admin
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect 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 django.utils.translation import get_language_from_request, ugettext_lazy as _
from parler.admin import TranslatableAdmin from parler.admin import TranslatableAdmin
@ -30,6 +30,30 @@ except ImportError:
pass 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): class BlogCategoryAdmin(EnhancedModelAdminMixin, ModelAppHookConfig, TranslatableAdmin):
form = CategoryAdminForm form = CategoryAdminForm
list_display = [ list_display = [
@ -55,7 +79,7 @@ class PostAdmin(PlaceholderAdminMixin, FrontendEditableAdminMixin,
'title', 'author', 'date_published', 'app_config', 'all_languages_column', 'title', 'author', 'date_published', 'app_config', 'all_languages_column',
'date_published_end' 'date_published_end'
] ]
list_filter = ('app_config',) search_fields = ('translations__title',)
date_hierarchy = 'date_published' date_hierarchy = 'date_published'
raw_id_fields = ['author'] raw_id_fields = ['author']
frontend_editable_fields = ('title', 'abstract', 'post_text') frontend_editable_fields = ('title', 'abstract', 'post_text')
@ -85,6 +109,21 @@ class PostAdmin(PlaceholderAdminMixin, FrontendEditableAdminMixin,
} }
_sites = None _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): def get_urls(self):
""" """
Customize the modeladmin urls 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>`_ * configure haystack according to `aldryn-search docs <https://github.com/aldryn/aldryn-search#usage>`_
and `haystack docs <http://django-haystack.readthedocs.io/en/stable/>`_. 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 Minimal configuration
********************* *********************

View file

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

View file

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

View file

@ -90,6 +90,52 @@ class AdminTest(BaseTest):
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
self.assertEqual(response['Location'], '/') 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): def test_admin_blogconfig_views(self):
post_admin = admin.site._registry[BlogConfig] post_admin = admin.site._registry[BlogConfig]
request = self.get_page_request('/', self.user, r'/en/blog/', edit=False) request = self.get_page_request('/', self.user, r'/en/blog/', edit=False)