diff --git a/django/contrib/admin/filterspecs.py b/django/contrib/admin/filterspecs.py
index eab5407..a18a6e5 100644
--- a/django/contrib/admin/filterspecs.py
+++ b/django/contrib/admin/filterspecs.py
@@ -76,7 +76,9 @@ class RelatedFilterSpec(FilterSpec):
             self.lookup_title = f.verbose_name # use field name
         rel_name = other_model._meta.pk.name
         self.lookup_kwarg = '%s__%s__exact' % (self.field_path, rel_name)
+        self.lookup_kwarg_isnull = '%s__isnull' % (self.field_path)
         self.lookup_val = request.GET.get(self.lookup_kwarg, None)
+        self.lookup_val_isnull = bool(request.GET.get(self.lookup_kwarg_isnull, None))
         self.lookup_choices = f.get_choices(include_blank=False)
 
     def has_output(self):
@@ -86,13 +88,18 @@ class RelatedFilterSpec(FilterSpec):
         return self.lookup_title
 
     def choices(self, cl):
-        yield {'selected': self.lookup_val is None,
-               'query_string': cl.get_query_string({}, [self.lookup_kwarg]),
+        from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE
+        yield {'selected': self.lookup_val is None and not self.lookup_val_isnull,
+               'query_string': cl.get_query_string({}, [self.lookup_kwarg, self.lookup_kwarg_isnull]),
                'display': _('All')}
         for pk_val, val in self.lookup_choices:
             yield {'selected': self.lookup_val == smart_unicode(pk_val),
-                   'query_string': cl.get_query_string({self.lookup_kwarg: pk_val}),
+                   'query_string': cl.get_query_string({self.lookup_kwarg: pk_val}, [self.lookup_kwarg_isnull]),
                    'display': val}
+        if hasattr(self.field, 'rel') and self.field.null:
+            yield {'selected': self.lookup_val_isnull,
+                   'query_string': cl.get_query_string({self.lookup_kwarg_isnull: 'True'}, [self.lookup_kwarg]),
+                   'display': EMPTY_CHANGELIST_VALUE}
 
 FilterSpec.register(lambda f: (
         hasattr(f, 'rel') and bool(f.rel) or
@@ -192,8 +199,11 @@ class AllValuesFilterSpec(FilterSpec):
         super(AllValuesFilterSpec, self).__init__(f, request, params, model,
                                                   model_admin,
                                                   field_path=field_path)
-        self.lookup_val = request.GET.get(self.field_path, None)
-        parent_model, reverse_path = reverse_field_path(model, field_path)
+        self.lookup_kwarg = self.field_path
+        self.lookup_kwarg_isnull = '%s__isnull' % self.field_path
+        self.lookup_val = request.GET.get(self.lookup_kwarg, None)
+        self.lookup_val_isnull = request.GET.get(self.lookup_kwarg_isnull, None)
+        parent_model, reverse_path = reverse_field_path(model, self.field_path)
         queryset = parent_model._default_manager.all()
         # optional feature: limit choices base on existing relationships
         # queryset = queryset.complex_filter(
@@ -202,18 +212,30 @@ class AllValuesFilterSpec(FilterSpec):
         queryset = queryset.filter(limit_choices_to)
 
         self.lookup_choices = \
-            queryset.distinct().order_by(f.name).values(f.name)
+            queryset.distinct().order_by(f.name).values_list(f.name, flat=True)
 
     def title(self):
         return self.field.verbose_name
 
     def choices(self, cl):
-        yield {'selected': self.lookup_val is None,
-               'query_string': cl.get_query_string({}, [self.field_path]),
+        from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE
+        yield {'selected': self.lookup_val is None and self.lookup_val_isnull is None,
+               'query_string': cl.get_query_string({}, [self.lookup_kwarg, self.lookup_kwarg_isnull]),
                'display': _('All')}
+        include_none = False
+        
         for val in self.lookup_choices:
-            val = smart_unicode(val[self.field.name])
+            if val is None:
+                include_none = True
+                continue
+            val = smart_unicode(val)
+            
             yield {'selected': self.lookup_val == val,
-                   'query_string': cl.get_query_string({self.field_path: val}),
+                   'query_string': cl.get_query_string({self.lookup_kwarg: val}, [self.lookup_kwarg_isnull]),
                    'display': val}
+        if include_none:
+            yield {'selected': self.lookup_val_isnull is not None,
+                    'query_string': cl.get_query_string({self.lookup_kwarg_isnull: 'True'}, [self.lookup_kwarg]),
+                    'display': EMPTY_CHANGELIST_VALUE}
+
 FilterSpec.register(lambda f: True, AllValuesFilterSpec)
diff --git a/tests/regressiontests/admin_filterspecs/__init__.py b/tests/regressiontests/admin_filterspecs/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/regressiontests/admin_filterspecs/models.py b/tests/regressiontests/admin_filterspecs/models.py
new file mode 100644
index 0000000..e62a070
--- /dev/null
+++ b/tests/regressiontests/admin_filterspecs/models.py
@@ -0,0 +1,8 @@
+from django.db import models
+from django.contrib.auth.models import User
+
+class Book(models.Model):
+    title = models.CharField(max_length=25)
+    year = models.PositiveIntegerField(null=True, blank=True)
+    author = models.ForeignKey(User, related_name='books_authored', blank=True, null=True)
+    contributors = models.ManyToManyField(User, related_name='books_contributed', blank=True, null=True)
diff --git a/tests/regressiontests/admin_filterspecs/tests.py b/tests/regressiontests/admin_filterspecs/tests.py
new file mode 100644
index 0000000..e8be8cf
--- /dev/null
+++ b/tests/regressiontests/admin_filterspecs/tests.py
@@ -0,0 +1,119 @@
+from django.test import TestCase
+from django.test.client import RequestFactory
+from django.contrib.auth.models import User
+
+from django.contrib import admin
+from django.contrib.admin.views.main import ChangeList
+
+from models import Book
+
+class FilterSpecsTests(TestCase):
+    
+    def setUp(self):
+        # Users
+        alfred = User.objects.create_user('alfred', 'alfred@example.com')
+        bob = User.objects.create_user('bob', 'alfred@example.com')
+        lisa = User.objects.create_user('lisa', 'lisa@example.com')
+        
+        #Books
+        bio_book = Book.objects.create(title='Django: a biography', year=1999, author=alfred)
+        django_book = Book.objects.create(title='The Django Book', year=None, author=bob)
+        gipsy_book = Book.objects.create(title='Gipsy guitar for dummies', year=2002)
+        gipsy_book.contributors = [bob, lisa]
+        gipsy_book.save()
+        
+        self.request_factory = RequestFactory()
+        
+    def test_AllValuesFilterSpec(self):
+        modeladmin = BookAdmin(Book, admin.site)
+        
+        request = self.request_factory.get('/', {'year__isnull': 'True'})
+        changelist = ChangeList(request, Book, modeladmin.list_display, modeladmin.list_display_links,
+            modeladmin.list_filter, modeladmin.date_hierarchy, modeladmin.search_fields,
+            modeladmin.list_select_related, modeladmin.list_per_page, modeladmin.list_editable, modeladmin)
+            
+        # Make sure changelist.get_query_set() does not raise IncorrectLookupParameters
+        queryset = changelist.get_query_set()
+
+        # Make sure the last choice is None and is selected
+        filterspec = changelist.get_filters(request)[0][0]
+        self.assertEquals(filterspec.title(), u'year')
+        choices = list(filterspec.choices(changelist))
+        self.assertEquals(choices[3]['selected'], True)
+        self.assertEquals(choices[3]['query_string'], '?year__isnull=True')
+        
+        request = self.request_factory.get('/', {'year': '2002'})
+        changelist = ChangeList(request, Book, modeladmin.list_display, modeladmin.list_display_links,
+            modeladmin.list_filter, modeladmin.date_hierarchy, modeladmin.search_fields,
+            modeladmin.list_select_related, modeladmin.list_per_page, modeladmin.list_editable, modeladmin)
+            
+        # Make sure the correct choice is selected    
+        filterspec = changelist.get_filters(request)[0][0]
+        self.assertEquals(filterspec.title(), u'year')
+        choices = list(filterspec.choices(changelist))
+        self.assertEquals(choices[2]['selected'], True)
+        self.assertEquals(choices[2]['query_string'], '?year=2002')
+        
+    def test_RelatedFilterSpec_ForeignKey(self):
+        modeladmin = BookAdmin(Book, admin.site)
+        
+        request = self.request_factory.get('/', {'author__isnull': 'True'})
+        changelist = ChangeList(request, Book, modeladmin.list_display, modeladmin.list_display_links,
+            modeladmin.list_filter, modeladmin.date_hierarchy, modeladmin.search_fields,
+            modeladmin.list_select_related, modeladmin.list_per_page, modeladmin.list_editable, modeladmin)
+        
+        # Make sure changelist.get_query_set() does not raise IncorrectLookupParameters
+        queryset = changelist.get_query_set()
+
+        # Make sure the last choice is None and is selected
+        filterspec = changelist.get_filters(request)[0][1]
+        self.assertEquals(filterspec.title(), u'author')
+        choices = list(filterspec.choices(changelist))
+        self.assertEquals(choices[4]['selected'], True)
+        self.assertEquals(choices[4]['query_string'], '?author__isnull=True')
+        
+        request = self.request_factory.get('/', {'author__id__exact': '1'})
+        changelist = ChangeList(request, Book, modeladmin.list_display, modeladmin.list_display_links,
+            modeladmin.list_filter, modeladmin.date_hierarchy, modeladmin.search_fields,
+            modeladmin.list_select_related, modeladmin.list_per_page, modeladmin.list_editable, modeladmin)
+            
+        # Make sure the correct choice is selected
+        filterspec = changelist.get_filters(request)[0][1]
+        self.assertEquals(filterspec.title(), u'author')
+        choices = list(filterspec.choices(changelist))
+        self.assertEquals(choices[1]['selected'], True)
+        self.assertEquals(choices[1]['query_string'], '?author__id__exact=1')
+        
+    def test_RelatedFilterSpec_ManyToMany(self):
+        modeladmin = BookAdmin(Book, admin.site)
+        
+        request = self.request_factory.get('/', {'contributors__isnull': 'True'})
+        changelist = ChangeList(request, Book, modeladmin.list_display, modeladmin.list_display_links,
+            modeladmin.list_filter, modeladmin.date_hierarchy, modeladmin.search_fields,
+            modeladmin.list_select_related, modeladmin.list_per_page, modeladmin.list_editable, modeladmin)
+        
+        # Make sure changelist.get_query_set() does not raise IncorrectLookupParameters
+        queryset = changelist.get_query_set()
+
+        # Make sure the last choice is None and is selected
+        filterspec = changelist.get_filters(request)[0][2]
+        self.assertEquals(filterspec.title(), u'user')
+        choices = list(filterspec.choices(changelist))
+        self.assertEquals(choices[4]['selected'], True)
+        self.assertEquals(choices[4]['query_string'], '?contributors__isnull=True')
+        
+        request = self.request_factory.get('/', {'contributors__id__exact': '2'})
+        changelist = ChangeList(request, Book, modeladmin.list_display, modeladmin.list_display_links,
+            modeladmin.list_filter, modeladmin.date_hierarchy, modeladmin.search_fields,
+            modeladmin.list_select_related, modeladmin.list_per_page, modeladmin.list_editable, modeladmin)
+            
+        # Make sure the correct choice is selected
+        filterspec = changelist.get_filters(request)[0][2]
+        self.assertEquals(filterspec.title(), u'user')
+        choices = list(filterspec.choices(changelist))
+        self.assertEquals(choices[2]['selected'], True)
+        self.assertEquals(choices[2]['query_string'], '?contributors__id__exact=2')
+
+class BookAdmin(admin.ModelAdmin):
+    list_filter = ('year', 'author', 'contributors')
+    order_by = '-id'
