Index: docs/ref/contrib/admin/index.txt
===================================================================
--- docs/ref/contrib/admin/index.txt	(revision 17411)
+++ docs/ref/contrib/admin/index.txt	(working copy)
@@ -695,11 +695,23 @@
                   ('is_staff', BooleanFieldListFilter),
               )
 
-      .. note::
 
-          The ``FieldListFilter`` API is currently considered internal
-          and prone to refactoring.
+    .. note::
 
+        .. versionadded:: 1.4
+
+        It's possible customize the template used to display the filter, for example::
+
+            class AdvancedDecadeBornListFilter(DecadeBornListFilter):
+                template_name = "custom_template.html"
+
+
+
+    .. note::
+
+      The ``FieldListFilter`` API is currently considered internal
+      and prone to refactoring.
+
 .. attribute:: ModelAdmin.list_max_show_all
 
     .. versionadded:: 1.4
@@ -2027,3 +2039,5 @@
 :class:`ModelAdmin` instances described above. The ``opts`` variable can be any
 object which has an ``app_label`` and ``module_name`` and is usually supplied
 by the admin views for the current model.
+
+
Index: tests/regressiontests/admin_views/admin.py
===================================================================
--- tests/regressiontests/admin_views/admin.py	(revision 17411)
+++ tests/regressiontests/admin_views/admin.py	(working copy)
@@ -13,6 +13,7 @@
 from django.db import models
 from django.forms.models import BaseModelFormSet
 from django.http import HttpResponse
+from django.contrib.admin import BooleanFieldListFilter
 
 from .models import (Article, Chapter, Account, Media, Child, Parent, Picture,
     Widget, DooHickey, Grommet, Whatsit, FancyDoodad, Category, Link,
@@ -25,7 +26,7 @@
     CoverLetter, Story, OtherStory, Book, Promo, ChapterXtra1, Pizza, Topping,
     Album, Question, Answer, ComplexSortedPerson, PrePopulatedPostLargeSlug,
     AdminOrderedField, AdminOrderedModelMethod, AdminOrderedAdminMethod,
-    AdminOrderedCallable, Report)
+    AdminOrderedCallable, Report, Color2)
 
 
 def callable_year(dt_value):
@@ -512,6 +513,12 @@
                 name='cable_extra'),
         )
 
+class CustomTemplateBooleanFieldListFilter(BooleanFieldListFilter):
+    template_name = 'custom_filter_template.html'
+
+class CustomTemplateFilterColorAdmin(admin.ModelAdmin):
+    list_filter = (('warm', CustomTemplateBooleanFieldListFilter),)
+
 site = admin.AdminSite(name="admin")
 site.register(Article, ArticleAdmin)
 site.register(CustomArticle, CustomArticleAdmin)
@@ -581,6 +588,7 @@
 site.register(AdminOrderedModelMethod, AdminOrderedModelMethodAdmin)
 site.register(AdminOrderedAdminMethod, AdminOrderedAdminMethodAdmin)
 site.register(AdminOrderedCallable, AdminOrderedCallableAdmin)
+site.register(Color2, CustomTemplateFilterColorAdmin)
 
 # Register core models we need in our tests
 from django.contrib.auth.models import User, Group
Index: tests/regressiontests/admin_views/tests.py
===================================================================
--- tests/regressiontests/admin_views/tests.py	(revision 17411)
+++ tests/regressiontests/admin_views/tests.py	(working copy)
@@ -573,6 +573,11 @@
         except SuspiciousOperation:
             self.fail("Filters should be allowed if they are defined on a ForeignKey pointing to this model")
 
+    def test_filter_with_custom_template(self):
+        response = self.client.get("/test_admin/admin/admin_views/color2/")
+        self.assertTrue('custom_filter_template.html' in [t.name for t in response.template])
+
+
 class AdminJavaScriptTest(AdminViewBasicTest):
     urls = "regressiontests.admin_views.urls"
 
Index: tests/regressiontests/admin_views/models.py
===================================================================
--- tests/regressiontests/admin_views/models.py	(revision 17411)
+++ tests/regressiontests/admin_views/models.py	(working copy)
@@ -106,6 +106,10 @@
     def __unicode__(self):
         return self.value
 
+# we replicate Color to register with another ModelAdmin
+class Color2(Color):
+    class Meta:
+        proxy = True
 
 class Thing(models.Model):
     title = models.CharField(max_length=20)
Index: tests/regressiontests/admin_views/templates/custom_filter_template.html
===================================================================
Index: django/contrib/admin/templatetags/admin_list.py
===================================================================
--- django/contrib/admin/templatetags/admin_list.py	(revision 17411)
+++ django/contrib/admin/templatetags/admin_list.py	(working copy)
@@ -13,8 +13,9 @@
 from django.utils.translation import ugettext as _
 from django.utils.encoding import smart_unicode, force_unicode
 from django.template import Library
+from django.template.loader import get_template
+from django.template.context import Context
 
-
 register = Library()
 
 DOT = '.'
@@ -360,9 +361,14 @@
         'search_var': SEARCH_VAR
     }
 
-@register.inclusion_tag('admin/filter.html')
+@register.simple_tag()
 def admin_list_filter(cl, spec):
-    return {'title': spec.title, 'choices' : list(spec.choices(cl))}
+    if hasattr(spec, 'template_name') and spec.template_name:
+        t = get_template(spec.template_name)
+    else:
+        t = get_template('admin/filter.html')
+    ctx = Context({'title': spec.title, 'choices' : list(spec.choices(cl)), 'spec': spec})
+    return t.render(ctx)
 
 @register.inclusion_tag('admin/actions.html', takes_context=True)
 def admin_actions(context):
