from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.utils.encoding import smart_unicode
from django.utils.translation import ugettext as _

import moderation


def _registered_content_types():
    "Return sorted content types for all registered models."
    content_types = []
    registered = moderation.moderation._registered_models.keys()
    registered.sort(key=lambda obj: obj.__name__)
    for model in registered:
        content_types.append(ContentType.objects.get_for_model(model))
    return content_types


try:
    from django.contrib.admin.filters import FieldListFilter
except ImportError:
    # Django < 1.4
    from django.contrib.admin.filterspecs import FilterSpec, RelatedFilterSpec

    class ContentTypeFilterSpec(RelatedFilterSpec):

        def __init__(self, *args, **kwargs):
            super(ContentTypeFilterSpec, self).__init__(*args, **kwargs)
            self.content_types = _registered_content_types()
            self.lookup_choices = map(
                lambda ct: (ct.id, ct.name.capitalize()), self.content_types)

    get_filter = lambda f: getattr(f, 'content_type_filter', False)
    FilterSpec.filter_specs.insert(0, (get_filter, ContentTypeFilterSpec))
else:
    # Django >= 1.4
    class RegisteredContentTypeListFilter(FieldListFilter):
        def __init__(self, field, request, params,
                     model, model_admin, field_path):
            self.lookup_kwarg = '%s' % field_path
            self.lookup_val = request.GET.get(self.lookup_kwarg)
            self._types = _registered_content_types()
            super(RegisteredContentTypeListFilter, self).__init__(
                field, request, params, model, model_admin, field_path)

        def expected_parameters(self):
            return [self.lookup_kwarg]

        def choices(self, cl):
            yield {
                'selected': self.lookup_val is None,
                'query_string': cl.get_query_string({}, [self.lookup_kwarg]),
                'display': _('All')
            }
            for type in self._types:
                yield {
                    'selected': smart_unicode(type.id) == self.lookup_val,
                    'query_string': cl.get_query_string({
                        self.lookup_kwarg: type.id}),
                    'display': unicode(type),
                }

@@ -1557,24 +1557,31 @@
        self.
+content
 _types = _re
@@ -2072,16 +2072,19 @@
     for 
+ct_
 type in 
@@ -2088,16 +2088,23 @@
 in self.
+content
 _types:%0A
@@ -2169,24 +2169,27 @@
 art_unicode(
+ct_
 type.id) == 
@@ -2306,16 +2306,19 @@
 _kwarg: 
+ct_
 type.id%7D
@@ -2359,16 +2359,19 @@
 unicode(
+ct_
 type),%0A 

Use self.content_types to be more consistent with other filter spec. Don't shadow built-in type function.