Index: django/db/models/loading.py
===================================================================
--- django/db/models/loading.py	(revision 12973)
+++ django/db/models/loading.py	(working copy)
@@ -4,6 +4,7 @@
 from django.core.exceptions import ImproperlyConfigured
 from django.utils.datastructures import SortedDict
 from django.utils.importlib import import_module
+from django.utils.module_loading import module_has_submodule
 
 import imp
 import sys
@@ -72,29 +73,28 @@
         """
         self.handled[app_name] = None
         self.nesting_level += 1
+        models = None
         app_module = import_module(app_name)
-        try:
-            imp.find_module('models', app_module.__path__)
-        except ImportError: 
-            self.nesting_level -= 1
-            # App has no models module, that's not a problem.
-            return None
-        try:
-            models = import_module('.models', app_name)
-        except ImportError:
-            self.nesting_level -= 1
-            if can_postpone:
-                # Either the app has an error, or the package is still being
-                # imported by Python and the model module isn't available yet.
-                # We will check again once all the recursion has finished (in
-                # populate).
-                self.postponed.append(app_name)
-                return None
-            else:
-                raise
+
+        if module_has_submodule(app_module, 'models'):
+            try:
+                models = import_module('.models', app_name)
+            except ImportError:
+                self.nesting_level -= 1
+                if can_postpone:
+                    # Either the app has an error, or the package is still being
+                    # imported by Python and the model module isn't available yet.
+                    # We will check again once all the recursion has finished (in
+                    # populate).
+                    self.postponed.append(app_name)
+                    return None
+                else:
+                    raise
+
+            if models not in self.app_store:
+                self.app_store[models] = len(self.app_store)
+
         self.nesting_level -= 1
-        if models not in self.app_store:
-            self.app_store[models] = len(self.app_store)
         return models
 
     def app_cache_ready(self):
Index: django/utils/module_loading.py
===================================================================
--- django/utils/module_loading.py	(revision 0)
+++ django/utils/module_loading.py	(revision 0)
@@ -0,0 +1,27 @@
+import os
+import imp
+
+def module_has_submodule(mod, submod_name):
+    # If the module was loaded from an egg, __loader__ will be set and 
+    # its find_module must be used to search for submodules.
+    loader = getattr(mod, '__loader__', None)
+    if loader:
+        mod_path = "%s.%s" % (mod.__name__, submod_name)
+        mod_path = mod_path[len(loader.prefix):]
+        x = loader.find_module(mod_path)
+        if x is None:
+            # zipimport.zipimporter.find_module is documented to take
+            # dotted paths but in fact through Pyton 2.7 is observed 
+            # to require os.sep in place of dots...so try using os.sep
+            # if the dotted path version failed to find the requested 
+            # submodule.
+            x = loader.find_module(mod_path.replace('.', os.sep))
+        return x is not None
+
+    try:
+        imp.find_module(submod_name, mod.__path__)
+        return True
+    except ImportError:
+        return False
+
+

Property changes on: django/utils/module_loading.py
___________________________________________________________________
Added: svn:eol-style
   + native

Index: tests/regressiontests/app_loading/eggs/nomodelapp.egg
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tests/regressiontests/app_loading/eggs/nomodelapp.egg
___________________________________________________________________
Added: svn:executable
   + *
Added: svn:mime-type
   + application/octet-stream

Index: tests/regressiontests/app_loading/eggs/modelapp.egg
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tests/regressiontests/app_loading/eggs/modelapp.egg
___________________________________________________________________
Added: svn:executable
   + *
Added: svn:mime-type
   + application/octet-stream

Index: tests/regressiontests/app_loading/eggs/omelet.egg
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tests/regressiontests/app_loading/eggs/omelet.egg
___________________________________________________________________
Added: svn:executable
   + *
Added: svn:mime-type
   + application/octet-stream

Index: tests/regressiontests/app_loading/tests.py
===================================================================
--- tests/regressiontests/app_loading/tests.py	(revision 12973)
+++ tests/regressiontests/app_loading/tests.py	(working copy)
@@ -1,8 +1,10 @@
 import os
 import sys
 import time
+from unittest import TestCase
 
 from django.conf import Settings
+from django.db.models.loading import load_app
 
 __test__ = {"API_TESTS": """
 Test the globbing of INSTALLED_APPS.
@@ -25,3 +27,35 @@
 
 """}
 
+class EggLoadingTest(TestCase):
+
+    def setUp(self):
+        self.old_path = sys.path
+        self.egg_dir = '%s/eggs' % os.path.dirname(__file__)
+
+    def tearDown(self):
+        sys.path = self.old_path
+
+    def test_egg1(self):
+        egg_name = '%s/modelapp.egg' % self.egg_dir
+        sys.path.append(egg_name)
+        models = load_app('app_with_models')
+        self.failIf(models is None)
+
+    def test_egg2(self):
+        egg_name = '%s/nomodelapp.egg' % self.egg_dir
+        sys.path.append(egg_name)
+        models = load_app('app_no_models')
+        self.failUnless(models is None)
+
+    def test_egg3(self):
+        egg_name = '%s/omelet.egg' % self.egg_dir
+        sys.path.append(egg_name)
+        models = load_app('omelet.app_with_models')
+        self.failIf(models is None)
+
+    def test_egg4(self):
+        egg_name = '%s/omelet.egg' % self.egg_dir
+        sys.path.append(egg_name)
+        models = load_app('omelet.app_no_models')
+        self.failUnless(models is None)
