Index: media/js/admin/RelatedObjectLookups.js
===================================================================
--- media/js/admin/RelatedObjectLookups.js	(revision 6240)
+++ media/js/admin/RelatedObjectLookups.js	(working copy)
@@ -19,7 +19,7 @@
 function dismissRelatedLookupPopup(win, chosenId) {
     var name = win.name.replace(/___/g, '.');
     var elem = document.getElementById(name);
-    if (elem.className.indexOf('vRawIdAdminField') != -1 && elem.value) {
+    if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
         elem.value += ',' + chosenId;
     } else {
         document.getElementById(name).value = chosenId;
Index: options.py
===================================================================
--- options.py	(revision 6240)
+++ options.py	(working copy)
@@ -168,13 +168,15 @@
         if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
             if isinstance(db_field, models.ForeignKey) and db_field.name in self.raw_id_fields:
                 kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel)
-                return db_field.formfield(**kwargs)
             else:
-                # Wrap the widget's render() method with a method that adds
-                # extra HTML to the end of the rendered output.
-                formfield = db_field.formfield(**kwargs)
-                formfield.widget.render = widgets.RelatedFieldWidgetWrapper(formfield.widget.render, db_field.rel, self.admin_site)
-                return formfield
+                if isinstance(db_field, models.ManyToManyField) and db_field.name in self.raw_id_fields:
+                    kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel)
+                    kwargs['help_text'] = ''
+            # Wrap the widget's render() method with a method that adds
+            # extra HTML to the end of the rendered output.
+            formfield = db_field.formfield(**kwargs)
+            formfield.widget.render = widgets.RelatedFieldWidgetWrapper(formfield.widget.render, db_field.rel, self.admin_site)
+            return formfield
 
         # For any other type of field, just call its formfield() method.
         return db_field.formfield(**kwargs)
Index: widgets.py
===================================================================
--- widgets.py	(revision 6240)
+++ widgets.py	(working copy)
@@ -3,6 +3,7 @@
 """
 
 from django import newforms as forms
+from django.utils.datastructures import MultiValueDict
 from django.utils.text import capfirst
 from django.utils.translation import ugettext as _
 from django.conf import settings
@@ -75,7 +76,8 @@
             url = '?' + '&amp;'.join(['%s=%s' % (k, v) for k, v in self.rel.limit_choices_to.items()])
         else:
             url = ''
-        attrs['class'] = 'vRawIdAdminField' # The JavaScript looks for this hook.
+        if not attrs.has_key('class'):
+          attrs['class'] = 'vForeignKeyRawIdAdminField' # The JavaScript looks for this hook.
         output = [super(ForeignKeyRawIdWidget, self).render(name, value, attrs)]
         # TODO: "id_" is hard-coded here. This should instead use the correct
         # API to determine the ID dynamically.
@@ -85,7 +87,28 @@
         return u''.join(output)
         #if self.change: # TODO
             #output.append('&nbsp;<strong>TODO</strong>')
+            
+class ManyToManyRawIdWidget(ForeignKeyRawIdWidget):
+    """
+    A Widget for displaying ManyToMany ids in the "raw_id" interface rather than
+    in a <select multiple> box.
+    """
+    def __init__(self, rel, attrs=None):
+        super(ManyToManyRawIdWidget, self).__init__(rel, attrs)
+    
+    def render(self, name, value, attrs=None):
+        attrs['class'] = 'vManyToManyRawIdAdminField'
+        if value: 
+            value = ','.join(value)
+        else: 
+            value = ""
+        return super(ManyToManyRawIdWidget, self).render(name, value, attrs)
 
+    def value_from_datadict(self, data, files, name):
+        if isinstance(data, MultiValueDict):
+            return data[name].split(',')
+        return data.get(name, None)
+
 class RelatedFieldWidgetWrapper(object):
     """
     This class is a wrapper whose __call__() method mimics the interface of a
