diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
index 8cc174bdfb..e2313e08fd 100644
--- a/django/db/models/fields/related.py
+++ b/django/db/models/fields/related.py
@@ -1663,11 +1663,8 @@ class ManyToManyField(RelatedField):
         Return the value of this field in the given model instance.
         """
         if obj.pk is None:
-            return []
-        qs = getattr(obj, self.attname).all()
-        if qs._result_cache is not None:
-            return [item.pk for item in qs]
-        return list(qs.values_list('pk', flat=True))
+            return self.related_model.objects.none()
+        return getattr(obj, self.attname).all()
 
     def save_form_data(self, instance, data):
         getattr(instance, self.attname).set(data)
diff --git a/tests/model_fields/test_manytomanyfield.py b/tests/model_fields/test_manytomanyfield.py
index 3134a33197..e4f1c0469d 100644
--- a/tests/model_fields/test_manytomanyfield.py
+++ b/tests/model_fields/test_manytomanyfield.py
@@ -12,7 +12,9 @@ class ManyToManyFieldTests(SimpleTestCase):
             m2m = models.ManyToManyField('self', models.CASCADE)
 
         instance = ManyToManyModel()
-        self.assertEqual(instance._meta.get_field('m2m').value_from_object(instance), [])
+        qs = instance._meta.get_field('m2m').value_from_object(instance)
+        self.assertEqual(qs.model, ManyToManyModel)
+        self.assertEqual(list(qs), [])
 
     def test_abstract_model_pending_operations(self):
         """
diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py
index 40260538c8..9de1a7f24b 100644
--- a/tests/model_forms/tests.py
+++ b/tests/model_forms/tests.py
@@ -963,78 +963,6 @@ class UniqueTest(TestCase):
         self.assertEqual(form.errors['title'], ["Post's Title not unique for Posted date."])
 
 
-class ModelToDictTests(TestCase):
-    """
-    Tests for forms.models.model_to_dict
-    """
-    def test_model_to_dict_many_to_many(self):
-        categories = [
-            Category(name='TestName1', slug='TestName1', url='url1'),
-            Category(name='TestName2', slug='TestName2', url='url2'),
-            Category(name='TestName3', slug='TestName3', url='url3')
-        ]
-        for c in categories:
-            c.save()
-        writer = Writer(name='Test writer')
-        writer.save()
-
-        art = Article(
-            headline='Test article',
-            slug='test-article',
-            pub_date=datetime.date(1988, 1, 4),
-            writer=writer,
-            article='Hello.'
-        )
-        art.save()
-        for c in categories:
-            art.categories.add(c)
-        art.save()
-
-        with self.assertNumQueries(1):
-            d = model_to_dict(art)
-
-        # Ensure all many-to-many categories appear in model_to_dict
-        for c in categories:
-            self.assertIn(c.pk, d['categories'])
-        # Ensure many-to-many relation appears as a list
-        self.assertIsInstance(d['categories'], list)
-
-    def test_reuse_prefetched(self):
-        # model_to_dict should not hit the database if it can reuse
-        # the data populated by prefetch_related.
-        categories = [
-            Category(name='TestName1', slug='TestName1', url='url1'),
-            Category(name='TestName2', slug='TestName2', url='url2'),
-            Category(name='TestName3', slug='TestName3', url='url3')
-        ]
-        for c in categories:
-            c.save()
-        writer = Writer(name='Test writer')
-        writer.save()
-
-        art = Article(
-            headline='Test article',
-            slug='test-article',
-            pub_date=datetime.date(1988, 1, 4),
-            writer=writer,
-            article='Hello.'
-        )
-        art.save()
-        for c in categories:
-            art.categories.add(c)
-
-        art = Article.objects.prefetch_related('categories').get(pk=art.pk)
-
-        with self.assertNumQueries(0):
-            d = model_to_dict(art)
-
-        # Ensure all many-to-many categories appear in model_to_dict
-        for c in categories:
-            self.assertIn(c.pk, d['categories'])
-        # Ensure many-to-many relation appears as a list
-        self.assertIsInstance(d['categories'], list)
-
-
 class ModelFormBasicTests(TestCase):
     def create_basic_data(self):
         self.c1 = Category.objects.create(
@@ -1788,6 +1716,25 @@ class ModelMultipleChoiceFieldTests(TestCase):
         sql, params = queryset.query.sql_with_params()
         self.assertEqual(len(params), 1)
 
+    def test_to_field_name_with_initial_data(self):
+        class ArticleCategoriesForm(forms.ModelForm):
+            categories = forms.ModelMultipleChoiceField(Category.objects.all(), to_field_name='slug')
+
+            class Meta:
+                model = Article
+                fields = ['categories']
+
+        article = Article.objects.create(
+            headline='Test article',
+            slug='test-article',
+            pub_date=datetime.date(1988, 1, 4),
+            writer=Writer.objects.create(name='Test writer'),
+            article='Hello.',
+        )
+        article.categories.add(self.c2, self.c3)
+        form = ArticleCategoriesForm(instance=article)
+        self.assertEqual(form['categories'].value(), [self.c2.slug, self.c3.slug])
+
 
 class ModelOneToOneFieldTests(TestCase):
     def test_modelform_onetoonefield(self):