def register_custom_filters(): """ Register custom filters for the Django admin. This function is called in AppConfig.ready() (ralph.admin.apps). """ field_filter_mapper = [ (lambda f: bool(f.choices), ChoicesListFilter), (lambda f: isinstance(f, (models.DecimalField, models.IntegerField)), NumberListFilter), (lambda f: isinstance(f, (models.BooleanField, models.NullBooleanField)), BooleanListFilter), (lambda f: isinstance(f, (models.DateField)), DateListFilter), (lambda f: isinstance(f, (models.CharField, models.TextField, models. IntegerField)), TextListFilter), (lambda f: isinstance(f, TreeForeignKey), TreeRelatedFieldListFilter), (lambda f: (isinstance(f, models.ForeignKey) and not getattr( f, '_autocomplete', True)), RelatedFieldListFilter), (lambda f: isinstance(f, (models.ForeignKey, models.ManyToManyField)), RelatedAutocompleteFieldListFilter), (lambda f: isinstance(f, TaggableManager), TagsListFilter), ] for func, filter_class in field_filter_mapper: FieldListFilter.register(func, filter_class, take_priority=True)
def test_overridden_spec(self): # make sure the publishable filter spec # gets used when we use a publishable field class dummy_request(object): GET = {} spec = FieldListFilter.create(Page._meta.get_field('authors'), dummy_request, {}, Page, self.publishable_admin, None) self.failUnless(isinstance(spec, PublishableRelatedFieldListFilter))
def test_only_draft_shown(self): self.author = Author.objects.create(name='author') self.author.publish() self.failUnless(2, Author.objects.count()) # make sure the publishable filter spec # gets used when we use a publishable field class dummy_request(object): GET = {} spec = FieldListFilter.create(Page._meta.get_field('authors'), dummy_request, {}, Page, self.publishable_admin, None) lookup_choices = spec.lookup_choices self.failUnlessEqual(1, len(lookup_choices)) pk, label = lookup_choices[0] self.failUnlessEqual(self.author.id, pk)
def ready(self): register_checks() if cool_settings.ADMIN_FILTER_USE_SELECT: ListFilter.template = 'cool/admin/select_filter.html' if cool_settings.ADMIN_RELATED_FIELD_FILTER_USE_AUTOCOMPLETE: FieldListFilter.register(lambda f: f.remote_field, filters.AutocompleteFieldFilter, True) if cool_settings.ADMIN_DATE_FIELD_FILTER_USE_RANGE: FieldListFilter.register( lambda f: isinstance(f, models.DateTimeField), filters.DateTimeRangeFieldFilter, True) FieldListFilter.register(lambda f: isinstance(f, models.DateField), filters.DateRangeFieldFilter, True)
{}, [self.lookup_kwarg, self.lookup_kwarg_isnull]) else: query_string = cl.get_query_string( { self.lookup_kwarg: ','.join(pks), }, [self.lookup_kwarg_isnull]) yield { 'selected': selected, 'query_string': query_string, 'display': val, } # TODO: untested if (isinstance(self.field, models.related.RelatedObject) and self.field.field.null or hasattr(self.field, 'rel') and self.field.null): yield { 'selected': bool(self.lookup_val_isnull), 'query_string': cl.get_query_string({ self.lookup_kwarg_isnull: 'True', }, [self.lookup_kwarg]), 'display': EMPTY_CHANGELIST_VALUE, } FieldListFilter.register( lambda f: (hasattr(f, 'rel') and bool(f.rel) or isinstance( f, models.related.RelatedObject)), MultipleSelectionFieldListFilter, True)
return super(CountryField, self).validate(value, model_instance) if not self.editable: # Skip validation for non-editable fields. return if value: choices = [option_key for option_key, option_value in self.choices] for single_value in value: if single_value not in choices: raise exceptions.ValidationError( self.error_messages['invalid_choice'], code='invalid_choice', params={'value': single_value}, ) if not self.blank and value in self.empty_values: raise exceptions.ValidationError( self.error_messages['blank'], code='blank') def value_to_string(self, obj): """ Ensure data is serialized correctly. """ value = self.value_from_object(obj) return self.get_prep_value(value) FieldListFilter.register( lambda f: isinstance(f, CountryField), filters.CountryFilter)
yield { 'selected': self.lookup_val == val, 'query_string': cl.get_query_string({ self.lookup_kwarg: val, }, [self.lookup_kwarg_isnull]), 'display': TYPE[int(val)], } if include_none: yield { 'selected': bool(self.lookup_val_isnull), 'query_string': cl.get_query_string({ self.lookup_kwarg_isnull: 'True', }, [self.lookup_kwarg]), 'display': EMPTY_CHANGELIST_VALUE, } FieldListFilter.register(lambda f: True, AllValuesFieldListFilter) class DateFieldListFilter(FieldListFilter): def __init__(self, field, request, params, model, model_admin, field_path): self.field_generic = '%s__' % field_path self.date_params = dict([(k, v) for k, v in params.items() if k.startswith(self.field_generic)]) now = timezone.now() if timezone.is_aware(now): now = timezone.localtime(now) if isinstance(field, models.DateTimeField): today = now.replace(hour=0, minute=0, second=0, microsecond=0) else: # field is a models.DateField today = now.date()
FieldListFilter.register_front = classmethod(_register_front) class NullListFilter(FieldListFilter): fields = (models.CharField, models.IntegerField, models.FileField) def test(cls, field): return field.null and isinstance(field, cls.fields) and not field._choices test = classmethod(test) def __init__(self, field, request, params, model, model_admin, field_path): self.lookup_kwarg = '%s__isnull' % field.name self.lookup_val = request.GET.get(self.lookup_kwarg, None) super(NullListFilter, self).__init__(field, request, params, model, model_admin, field_path) def expected_parameters(self): return [self.lookup_kwarg, self.lookup_val] def choices(self, cl): # bool(v) must be False for IS NOT NULL and True for IS NULL, but can only be a string for k, v in ((_('All'), None), (_('Has value'), ''), (_('Omitted'), '1')): yield { 'selected': self.lookup_val == v, 'query_string': cl.get_query_string({self.lookup_kwarg: v}), 'display': k } FieldListFilter.register_front(NullListFilter.test, NullListFilter)
from django.template import RequestContext from django.utils.safestring import mark_safe from django_monitor.actions import ( approve_selected, challenge_selected, reset_to_pending ) from django_monitor.filter import MonitorFilter from django_monitor import model_from_queue, queued_models from django_monitor.conf import ( PENDING_STATUS, CHALLENGED_STATUS, APPROVED_STATUS, PENDING_DESCR, CHALLENGED_DESCR ) from django_monitor.models import MonitorEntry # Our objective is to place the custom monitor-filter on top FieldListFilter.register(lambda f: getattr(f, 'monitor_filter', False), MonitorFilter) class MEAdmin(admin.ModelAdmin): """ A special admin-class for aggregating moderation summary, not to let users add/edit/delete MonitorEntry objects directly. MonitorEntry works from behind the curtain. This admin class is to provide a single stop for users to get notified about pending/challenged model objects. """ change_list_template = 'admin/django_monitor/monitorentry/change_list.html' def get_urls(self): """ The only url allowed is that for changelist_view. """ from django.conf.urls.defaults import patterns, url
#! /usr/bin/env python #coding=utf-8 import datetime from django.db import models from django.contrib.admin.filters import FieldListFilter, DateFieldListFilter as OldDateFieldListFilter class DateFieldListFilter(OldDateFieldListFilter): def __init__(self, *args, **kwargs): super(DateFieldListFilter, self).__init__(*args, **kwargs) today = datetime.date.today() yesterday = today - datetime.timedelta(days=1) links = list(self.links) links.insert( 2, (u'昨天', { self.lookup_kwarg_year: str(yesterday.year), self.lookup_kwarg_month: str(yesterday.month), self.lookup_kwarg_day: str(yesterday.day), }), ) self.links = tuple(links) FieldListFilter.register(lambda f: isinstance(f, models.DateField), DateFieldListFilter, True)
'display': _('All') } for pk, title in self.lookup_choices: yield { 'selected': pk == int(self.lookup_val or '0'), 'query_string': cl.get_query_string({self.lookup_kwarg: pk}), 'display': mark_safe(smart_unicode(title)) } def title(self): return _('Category') if legacy: # registering the filter FieldListFilter.filter_specs.insert( 0, (lambda f: getattr(f, 'parent_filter', False), ParentFieldListFilter)) FieldListFilter.filter_specs.insert( 1, (lambda f: getattr(f, 'category_filter', False), CategoryFieldListFilter)) else: FieldListFilter.register(lambda f: getattr(f, 'parent_filter', False), ParentFieldListFilter, take_priority=True) FieldListFilter.register(lambda f: getattr(f, 'category_filter', False), CategoryFieldListFilter, take_priority=True)
from django.contrib.admin.filters import FieldListFilter, ChoicesFieldListFilter from .fields import PrimaryContentTypeField FieldListFilter.register( lambda f: isinstance(f, PrimaryContentTypeField), ChoicesFieldListFilter, take_priority=True)
def queryset(self, request, queryset): if self.form.is_valid(): filter_params = dict( filter(lambda x: bool(x[1]), self.form.cleaned_data.items())) if filter_params.get(self.lookup_kwarg_upto) is not None: value = filter_params.pop(self.lookup_kwarg_upto) filter_params['%s__lt' % self.field_path] = value + datetime.timedelta( days=1) return queryset.filter(**filter_params) else: return queryset FieldListFilter.register(lambda f: isinstance(f, DateField), EDateRangeFilter) class ENotNullFilter(admin.SimpleListFilter): """ Filter by null fields, for example for Foreign Key :param title: Title of filter :param parameter_name: Field name """ title = _('Filter title not set') parameter_name = 'parameter name not set' def lookups(self, request, model_admin): return ( ('not_null', _('Not empty only')),
yield { 'selected': pk == int(self.lookup_val or settings.SITE_ID), 'query_string': cl.get_query_string({self.lookup_kwarg: pk}), 'display': title, } def title(self): return _('Site') # Register the custom admin filter if legacy: FieldListFilter.filter_specs.insert(0, (lambda f: isinstance(f, SiteForeignKey), SiteFieldListFilter)) else: FieldListFilter.register(lambda f: getattr(f, 'site_filter', False), SiteFieldListFilter, take_priority=True) def current_site(queryset): return queryset.filter(site=Site.objects.get_current()) def register(cls, admin_cls): "Add a foreign key on Site to the Page model" cls.add_to_class('site', SiteForeignKey(Site, verbose_name=_('Site'), default=settings.SITE_ID, )) PageManager.add_to_active_filters(current_site, key='current_site')
def __new__(cls, *args, **kwargs): filter_instance = FieldListFilter.create(*args, **kwargs) filter_instance.title = title return filter_instance
#! /usr/bin/env python #coding=utf-8 import datetime from django.db import models from django.contrib.admin.filters import FieldListFilter, DateFieldListFilter as OldDateFieldListFilter class DateFieldListFilter(OldDateFieldListFilter): def __init__(self, *args, **kwargs): super(DateFieldListFilter, self).__init__(*args, **kwargs) today = datetime.date.today() yesterday = today - datetime.timedelta(days=1) links = list(self.links) links.insert(2, (u'昨天', { self.lookup_kwarg_year: str(yesterday.year), self.lookup_kwarg_month: str(yesterday.month), self.lookup_kwarg_day: str(yesterday.day), }), ) self.links = tuple(links) FieldListFilter.register( lambda f: isinstance(f, models.DateField), DateFieldListFilter, True)
'query_string': cl.get_query_string({}, [self.lookup_kwarg]), 'display': {'pk' : 'all', 'parent_pk' : None, 'val': _('All')} } for item in self.lookup_choices: parent_pk_val = None if item.parent: parent_pk_val = item.parent.pk yield { 'filtered_out': self.filtered_out.has_key(item.pk), 'selected': self.lookup_val == smart_unicode(item.pk), 'query_string': cl.get_query_string({self.lookup_kwarg: item.pk}), 'display': { 'pk': item.pk, 'parent_pk': parent_pk_val, 'val': ("%s %s" % ("-" * item.get_level(), unicode(item))).strip(), }, } FieldListFilter.register(lambda f: bool(f.rel) and getattr(f.rel.to, 'is_hierarchical', False), HierarchyRelatedFilterSpec) """ as the newly registered FilterSpec class is at the end of the test_list now, it would never be tested! So, wo push the newly created class at the top of filter_specs """ #tmp = FilterSpec.filter_specs.pop() #FilterSpec.filter_specs.insert(0, tmp)
def register_filters(): FieldListFilter.register(is_publishable_filter, PublishableRelatedFieldListFilter, take_priority=True)
list_filter = ('document','date', 'lang',) search_fields = ('document__name', 'version',) class LegalDocumentAcceptanceAdmin(BaseModelAdmin): """ Administration class """ list_display = ('__unicode__','timestamp','documentversion','user','desc') list_filter = ('timestamp','documentversion','user',) search_fields = ('documentversion__document__name','documentversion__version','user__first_name','user__last_name','desc','data',) class ContactMessageAdmin(BaseModelAdmin): """ Contact message administration class """ list_display = ('timestamp','name','email','ip','replied') search_fields = ('name','email','ip','text') list_filter = ('timestamp','replied',) # Admin models registration admin.site.register(SiteInfo, SiteInfoAdmin) admin.site.register(SiteLog, SiteLogAdmin) admin.site.register(LegalDocument, LegalDocumentAdmin) admin.site.register(LegalDocumentVersion, LegalDocumentVersionAdmin) admin.site.register(LegalDocumentAcceptance, LegalDocumentAcceptanceAdmin) admin.site.register(ContactMessage, ContactMessageAdmin) admin.site.register(DBTemplate) # Register enhanced field filters FieldListFilter.register( lambda f: isinstance(f, models.DateField), EnhancedDateFieldListFilter,take_priority=True)
class UserExtAdmin(XminAdmin, UserAdmin): pass class GroupExtAdmin(XminAdmin, GroupAdmin): pass class ExtAdminTreeMixin(): def is_tree(self): pass class LazyRelatedFieldListFilter(RelatedFieldListFilter): def __init__(self, field, request, params, model, model_admin, field_path): # Prevent hit database query in RelatedFieldListFilter field.get_choices = (lambda include_blank=False: []) super().__init__(field, request, params, model, model_admin, field_path) admin.site.unregister([Group]) admin.site.register(User, UserExtAdmin) admin.site.register(Group, GroupExtAdmin) FieldListFilter.register(lambda f: ( bool(f.rel) if hasattr(f, 'rel') else isinstance(f, models.related.RelatedObject)), LazyRelatedFieldListFilter, take_priority=True)
return output def validate(self, value, model_instance): """ Use custom validation for when using a multiple countries field. """ if not self.multiple: return super(CountryField, self).validate(value, model_instance) if not self.editable: # Skip validation for non-editable fields. return if value: choices = [option_key for option_key, option_value in self.choices] for single_value in value: if single_value not in choices: raise exceptions.ValidationError( self.error_messages['invalid_choice'], code='invalid_choice', params={'value': single_value}, ) if not self.blank and value in self.empty_values: raise exceptions.ValidationError(self.error_messages['blank'], code='blank') FieldListFilter.register(lambda f: isinstance(f, CountryField), filters.CountryFilter)
Take choices from field's 'choices' attribute for 'ChoicesField' and use 'flatchoices' as usual for other fields. """ #: Just tidy up standard implementation for the sake of DRY principle. def _choice_item(is_selected, query_string, title): return { 'selected': is_selected, 'query_string': query_string, 'display': force_text(title), } yield _choice_item( self.lookup_val is None, cl.get_query_string({}, [self.lookup_kwarg]), _('All')) container = (self.field.choices if isinstance(self.field, ChoicesField) else self.field.flatchoices) for lookup, title in container: yield _choice_item( smart_text(lookup) == self.lookup_val, cl.get_query_string({self.lookup_kwarg: lookup}), title) FieldListFilter.register(lambda field: bool(field.choices), ChoicesFieldListFilter, take_priority=True)
from __future__ import absolute_import from django.contrib.admin.filters import FieldListFilter from .filters import ParentFieldListFilter, CategoryFieldListFilter FieldListFilter.register( lambda f: getattr(f, "parent_filter", False), ParentFieldListFilter, take_priority=True, ) FieldListFilter.register( lambda f: getattr(f, "category_filter", False), CategoryFieldListFilter, take_priority=True, )