Index: django/db/models/fields/__init__.py
===================================================================
--- django/db/models/fields/__init__.py	(revision 6777)
+++ django/db/models/fields/__init__.py	(working copy)
@@ -211,7 +211,7 @@
         "Returns field's value prepared for database lookup."
         if lookup_type in ('exact', 'regex', 'iregex', 'gt', 'gte', 'lt', 'lte', 'month', 'day', 'search'):
             return [value]
-        elif lookup_type in ('range', 'in'):
+        elif lookup_type in ('range', 'in', 'notin'):
             return value
         elif lookup_type in ('contains', 'icontains'):
             return ["%%%s%%" % prep_for_like_query(value)]
Index: django/db/models/query.py
===================================================================
--- django/db/models/query.py	(revision 6777)
+++ django/db/models/query.py	(working copy)
@@ -21,7 +21,7 @@
 # The list of valid query types
 QUERY_TERMS = (
     'exact', 'iexact', 'contains', 'icontains',
-    'gt', 'gte', 'lt', 'lte', 'in',
+    'gt', 'gte', 'lt', 'lte', 'in', 'notin',
     'startswith', 'istartswith', 'endswith', 'iendswith',
     'range', 'year', 'month', 'day', 'isnull', 'search',
     'regex', 'iregex',
@@ -806,6 +806,12 @@
             return '%s IN (%s)' % (field_sql, in_string)
         else:
             raise EmptyResultSet
+    elif lookup_type == 'notin':
+        in_string = ','.join(['%s' for id in value])
+        if in_string:
+            return '%s NOT IN (%s)' % (field_sql, in_string)
+        else:
+            raise EmptyResultSet
     elif lookup_type in ('range', 'year'):
         return '%s BETWEEN %%s AND %%s' % field_sql
     elif lookup_type in ('month', 'day'):
