Fixed #17515 -- Added ability to override the template of custom admin FilterSpec classes. Thanks, saxix and Julien Phalip.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@17483 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
875a5ea8d4
commit
4dbeb4bca4
|
@ -17,6 +17,7 @@ from django.contrib.admin.util import (get_model_from_relation,
|
||||||
|
|
||||||
class ListFilter(object):
|
class ListFilter(object):
|
||||||
title = None # Human-readable title to appear in the right sidebar.
|
title = None # Human-readable title to appear in the right sidebar.
|
||||||
|
template = 'admin/filter.html'
|
||||||
|
|
||||||
def __init__(self, request, params, model, model_admin):
|
def __init__(self, request, params, model, model_admin):
|
||||||
# This dictionary will eventually contain the request's query string
|
# This dictionary will eventually contain the request's query string
|
||||||
|
|
|
@ -13,7 +13,8 @@ from django.utils.text import capfirst
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
from django.utils.encoding import smart_unicode, force_unicode
|
from django.utils.encoding import smart_unicode, force_unicode
|
||||||
from django.template import Library
|
from django.template import Library
|
||||||
|
from django.template.loader import get_template
|
||||||
|
from django.template.context import Context
|
||||||
|
|
||||||
register = Library()
|
register = Library()
|
||||||
|
|
||||||
|
@ -360,9 +361,14 @@ def search_form(cl):
|
||||||
'search_var': SEARCH_VAR
|
'search_var': SEARCH_VAR
|
||||||
}
|
}
|
||||||
|
|
||||||
@register.inclusion_tag('admin/filter.html')
|
@register.simple_tag
|
||||||
def admin_list_filter(cl, spec):
|
def admin_list_filter(cl, spec):
|
||||||
return {'title': spec.title, 'choices' : list(spec.choices(cl))}
|
tpl = get_template(spec.template)
|
||||||
|
return tpl.render(Context({
|
||||||
|
'title': spec.title,
|
||||||
|
'choices' : list(spec.choices(cl)),
|
||||||
|
'spec': spec,
|
||||||
|
}))
|
||||||
|
|
||||||
@register.inclusion_tag('admin/actions.html', takes_context=True)
|
@register.inclusion_tag('admin/actions.html', takes_context=True)
|
||||||
def admin_actions(context):
|
def admin_actions(context):
|
||||||
|
|
|
@ -697,8 +697,18 @@ subclass::
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
The ``FieldListFilter`` API is currently considered internal
|
The ``FieldListFilter`` API is currently considered internal and prone
|
||||||
and prone to refactoring.
|
to refactoring.
|
||||||
|
|
||||||
|
.. versionadded:: 1.4
|
||||||
|
|
||||||
|
It is possible to specify a custom template for rendering a list filter::
|
||||||
|
|
||||||
|
class FilterWithCustomTemplate(SimpleListFilter):
|
||||||
|
template = "custom_template.html"
|
||||||
|
|
||||||
|
See the default template provided by django (``admin/filter.html``) for
|
||||||
|
a concrete example.
|
||||||
|
|
||||||
.. attribute:: ModelAdmin.list_max_show_all
|
.. attribute:: ModelAdmin.list_max_show_all
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ from django.conf.urls import patterns, url
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.forms.models import BaseModelFormSet
|
from django.forms.models import BaseModelFormSet
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
|
from django.contrib.admin import BooleanFieldListFilter
|
||||||
|
|
||||||
from .models import (Article, Chapter, Account, Media, Child, Parent, Picture,
|
from .models import (Article, Chapter, Account, Media, Child, Parent, Picture,
|
||||||
Widget, DooHickey, Grommet, Whatsit, FancyDoodad, Category, Link,
|
Widget, DooHickey, Grommet, Whatsit, FancyDoodad, Category, Link,
|
||||||
|
@ -25,7 +26,7 @@ from .models import (Article, Chapter, Account, Media, Child, Parent, Picture,
|
||||||
CoverLetter, Story, OtherStory, Book, Promo, ChapterXtra1, Pizza, Topping,
|
CoverLetter, Story, OtherStory, Book, Promo, ChapterXtra1, Pizza, Topping,
|
||||||
Album, Question, Answer, ComplexSortedPerson, PrePopulatedPostLargeSlug,
|
Album, Question, Answer, ComplexSortedPerson, PrePopulatedPostLargeSlug,
|
||||||
AdminOrderedField, AdminOrderedModelMethod, AdminOrderedAdminMethod,
|
AdminOrderedField, AdminOrderedModelMethod, AdminOrderedAdminMethod,
|
||||||
AdminOrderedCallable, Report)
|
AdminOrderedCallable, Report, Color2)
|
||||||
|
|
||||||
|
|
||||||
def callable_year(dt_value):
|
def callable_year(dt_value):
|
||||||
|
@ -525,6 +526,12 @@ class ReportAdmin(admin.ModelAdmin):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class CustomTemplateBooleanFieldListFilter(BooleanFieldListFilter):
|
||||||
|
template = 'custom_filter_template.html'
|
||||||
|
|
||||||
|
class CustomTemplateFilterColorAdmin(admin.ModelAdmin):
|
||||||
|
list_filter = (('warm', CustomTemplateBooleanFieldListFilter),)
|
||||||
|
|
||||||
site = admin.AdminSite(name="admin")
|
site = admin.AdminSite(name="admin")
|
||||||
site.register(Article, ArticleAdmin)
|
site.register(Article, ArticleAdmin)
|
||||||
site.register(CustomArticle, CustomArticleAdmin)
|
site.register(CustomArticle, CustomArticleAdmin)
|
||||||
|
@ -594,6 +601,7 @@ site.register(AdminOrderedField, AdminOrderedFieldAdmin)
|
||||||
site.register(AdminOrderedModelMethod, AdminOrderedModelMethodAdmin)
|
site.register(AdminOrderedModelMethod, AdminOrderedModelMethodAdmin)
|
||||||
site.register(AdminOrderedAdminMethod, AdminOrderedAdminMethodAdmin)
|
site.register(AdminOrderedAdminMethod, AdminOrderedAdminMethodAdmin)
|
||||||
site.register(AdminOrderedCallable, AdminOrderedCallableAdmin)
|
site.register(AdminOrderedCallable, AdminOrderedCallableAdmin)
|
||||||
|
site.register(Color2, CustomTemplateFilterColorAdmin)
|
||||||
|
|
||||||
# Register core models we need in our tests
|
# Register core models we need in our tests
|
||||||
from django.contrib.auth.models import User, Group
|
from django.contrib.auth.models import User, Group
|
||||||
|
|
|
@ -105,6 +105,10 @@ class Color(models.Model):
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.value
|
return self.value
|
||||||
|
|
||||||
|
# we replicate Color to register with another ModelAdmin
|
||||||
|
class Color2(Color):
|
||||||
|
class Meta:
|
||||||
|
proxy = True
|
||||||
|
|
||||||
class Thing(models.Model):
|
class Thing(models.Model):
|
||||||
title = models.CharField(max_length=20)
|
title = models.CharField(max_length=20)
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
<h3>By {{ filter_title }} (custom)</h3>
|
||||||
|
<ul>
|
||||||
|
{% for choice in choices %}
|
||||||
|
<li{% if choice.selected %} class="selected"{% endif %}>
|
||||||
|
<a href="{{ choice.query_string|iriencode }}">{{ choice.display }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
|
@ -1,6 +1,7 @@
|
||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
from __future__ import with_statement, absolute_import
|
from __future__ import with_statement, absolute_import
|
||||||
|
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
import datetime
|
import datetime
|
||||||
import urlparse
|
import urlparse
|
||||||
|
@ -593,6 +594,18 @@ class AdminViewFormUrlTest(TestCase):
|
||||||
self.assertTrue('form_url' in response.context, msg='form_url not present in response.context')
|
self.assertTrue('form_url' in response.context, msg='form_url not present in response.context')
|
||||||
self.assertEqual(response.context['form_url'], 'pony')
|
self.assertEqual(response.context['form_url'], 'pony')
|
||||||
|
|
||||||
|
def test_filter_with_custom_template(self):
|
||||||
|
"""
|
||||||
|
Ensure that one can use a custom template to render an admin filter.
|
||||||
|
Refs #17515.
|
||||||
|
"""
|
||||||
|
template_dirs = settings.TEMPLATE_DIRS + (
|
||||||
|
os.path.join(os.path.dirname(__file__), 'templates'),)
|
||||||
|
with self.settings(TEMPLATE_DIRS=template_dirs):
|
||||||
|
response = self.client.get("/test_admin/admin/admin_views/color2/")
|
||||||
|
self.assertTrue('custom_filter_template.html' in [t.name for t in response.templates])
|
||||||
|
|
||||||
|
|
||||||
class AdminJavaScriptTest(AdminViewBasicTest):
|
class AdminJavaScriptTest(AdminViewBasicTest):
|
||||||
urls = "regressiontests.admin_views.urls"
|
urls = "regressiontests.admin_views.urls"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue