diff --git a/django/contrib/contenttypes/models.py b/django/contrib/contenttypes/models.py
index d588ff4..f3543b3 100644
--- a/django/contrib/contenttypes/models.py
+++ b/django/contrib/contenttypes/models.py
@@ -17,7 +17,13 @@ def get_by_natural_key(self, app_label, model):
         return ct
 
     def _get_opts(self, model):
-        return model._meta.concrete_model._meta
+        if model._deferred:
+            # Deferred models shouldn't have their own content type since
+            # they're only dynamic wrappers to allow field deferring.
+            # We make sure to retreive options from the model they are proxying
+            # which can also be a proxy.
+            model = model._meta.proxy_for_model
+        return model._meta
 
     def _get_from_cache(self, opts):
         key = (opts.app_label, opts.object_name.lower())
diff --git a/tests/modeltests/proxy_models/tests.py b/tests/modeltests/proxy_models/tests.py
index b332103..18a578a 100644
--- a/tests/modeltests/proxy_models/tests.py
+++ b/tests/modeltests/proxy_models/tests.py
@@ -217,8 +217,10 @@ def _handler(*args, **kwargs):
         signals.post_save.disconnect(h6, sender=MyPersonProxy)
 
     def test_content_type(self):
+        # A model and a proxy of this model do not
+        # share the same ContentType see #17648
         ctype = ContentType.objects.get_for_model
-        self.assertTrue(ctype(Person) is ctype(OtherPerson))
+        self.assertFalse(ctype(Person) is ctype(OtherPerson))
 
     def test_user_userproxy_userproxyproxy(self):
         User.objects.create(name='Bruce')
diff --git a/tests/regressiontests/defer_regress/tests.py b/tests/regressiontests/defer_regress/tests.py
index 4afe39b..4e4d80c 100644
--- a/tests/regressiontests/defer_regress/tests.py
+++ b/tests/regressiontests/defer_regress/tests.py
@@ -169,6 +169,14 @@ def test_only_and_defer_usage_on_proxy_models(self):
         self.assertEqual(dp.name, proxy.name, msg=msg)
         self.assertEqual(dp.value, proxy.value, msg=msg)
 
+        # Instances of proxy models with deferred fields should
+        # return the content type of the proxy model (bug #17648)
+        ctype = ContentType.objects.get_for_model
+        c1 = ctype(Proxy.objects.all()[0])
+        c2 = ctype(Proxy.objects.defer("name")[0])
+        c3 = ctype(Proxy.objects.only("name")[0])
+        self.assertTrue(c1 is c2 is c3)
+
     def test_resolve_columns(self):
         rt = ResolveThis.objects.create(num=5.0, name='Foobar')
         qs = ResolveThis.objects.defer('num')
