--- a/django/core/management.py
+++ b/django/core/management.py
@@ -673,6 +673,67 @@ def inspectdb(db_name):
 
     introspection_module = get_introspection_module()
 
+    def topological_sort(cursor, introspection_module, table_names):
+        """
+        Generator, Sorting the table names in a way that there are no forward references, if possible.
+        Yields tuples ( table_name, forward_refs, comment_lines ) in an order that avoids forward references.
+        Here, forward_refs is a set of table names that are referenced with a forward reference
+        that could not be avoided since circular dependencies exist.
+        comment_lines is a list of comment lines for this table (about forward references)
+        """
+        # tables_in is a list [ (table_name, [ referenced_table_name ] ], excluding self references
+        tables_in = [(name, [val[1]
+                             for val in introspection_module.get_relations(cursor, name).values()
+                             if val[1] != name])
+                     for name in table_names]
+        # unhandled_tables contains all unhandled table_names as a set for quick lookup
+        unhandled_tables = set(table_names)
+        # tables_in contains all table_names that still need to be handled.
+        # Initially, sort all tables by number of references and lexically
+        # (to get a defined order that doesn't change from inspect to inspect)
+        tables_in.sort(lambda (name1,refs1),(name2,refs2): cmp(len(refs1),len(refs2)) or cmp(name1,name2))
+        # go through list until everything is handled
+        while tables_in != []:
+            for i, (table_name, refs) in enumerate(tables_in):
+                # does it have references to unhandled tables?
+                if not unhandled_tables.intersection(refs):
+                    # no, take it
+                    unhandled_tables.remove(table_name)
+                    del tables_in[i]
+                    yield (table_name, set(), [])
+                    break;
+            else:
+                # There is no element without forward references in tables_in
+                # i.e. we have circular references
+                # strategy: use the table that is referenced most often
+                # This will most probably break the cycle
+                # with the least number of trouble makers.
+                # --> First, build a cross-ref:
+                #     referrers[table_name] is a set of all unhandled tables referencing table_name
+                referrers = {}
+                max_refcount = -1
+                for table_name, refs in tables_in:
+                    for ref in refs:
+                        referrers.setdefault(ref,set()).add(table_name)
+                # first entry in table_name getting maximal references
+                for i, (table_name, refs) in enumerate(tables_in):
+                    refcount = len(referrers.get(table_name,set()))
+                    if refcount > max_refcount:
+                        max_refcount, candidate = (refcount, i)
+                # got it.
+                bad_table_name, forward_references = tables_in[candidate]
+                forward_references = unhandled_tables.intersection(forward_references)
+                bad_referrers = list(unhandled_tables.intersection(referrers[bad_table_name]))
+                bad_referrers.sort()
+                comments = ["# cyclic references detected at this point",
+                            "# %s contains these forward references: %s"
+                                % (bad_table_name, ", ".join(forward_references)),
+                            "# and is referenced by %s" % ", ".join(bad_referrers)]
+                unhandled_tables.remove(bad_table_name)
+                del tables_in[candidate]
+                yield (bad_table_name, set(forward_references), comments)
+        return
+
     def table2model(table_name):
         object_name = table_name.title().replace('_', '')
         return object_name.endswith('s') and object_name[:-1] or object_name
@@ -681,7 +742,6 @@ def inspectdb(db_name):
     cursor = connection.cursor()
     yield "# This is an auto-generated Django model module."
     yield "# You'll have to do the following manually to clean this up:"
-    yield "#     * Rearrange models' order"
     yield "#     * Make sure each model has one field with primary_key=True"
     yield "# Feel free to rename the models, but don't rename db_table values or field names."
     yield "#"
@@ -689,14 +749,24 @@ def inspectdb(db_name):
     yield "# into your database."
     yield ''
     yield 'from django.db import models'
-    yield ''
-    for table_name in introspection_module.get_table_list(cursor):
+    yield ''
+    for (table_name, forward_referenced_tables, comments
+        ) in (topological_sort(cursor, introspection_module,
+                               introspection_module.get_table_list(cursor))):
+        for comment in comments:
+            yield comment
         yield 'class %s(models.Model):' % table2model(table_name)
         try:
             relations = introspection_module.get_relations(cursor, table_name)
         except NotImplementedError:
             relations = {}
-        try:
+        # relation_count :: {other_table_name: ref_count}
+        # counts for each other table, how often it is referred by this table.
+        # (needed for the decision whether we need related_name attributes)
+        relation_count = {}
+        for (field_index, (field_index_other_table, other_table)) in relations.iteritems():
+            relation_count[other_table] = relation_count.setdefault(other_table,0) + 1
+        try:
             indexes = introspection_module.get_indexes(cursor, table_name)
         except NotImplementedError:
             indexes = {}
@@ -710,14 +780,19 @@ def inspectdb(db_name):
                 att_name += '_field'
                 comment_notes.append('Field renamed because it was a Python reserved word.')
 
-            if relations.has_key(i):
+            if (relations.has_key(i)
+                and relations[i][1] not in forward_referenced_tables):
                 rel_to = relations[i][1] == table_name and "'self'" or table2model(relations[i][1])
-                field_type = 'ForeignKey(%s' % rel_to
+                field_type = "ForeignKey(%s" % rel_to
                 if att_name.endswith('_id'):
                     att_name = att_name[:-3]
                 else:
                     extra_params['db_column'] = att_name
-            else:
+                if relation_count[relations[i][1]] > 1:
+                    extra_params['related_name'] = '%s_by_%s' % (table_name, att_name)
+            else:
+                if relations.has_key(i):
+                    comment_notes.append('This is a forward foreign key reference to %s.' % table2model(relations[i][1]))
                 try:
                     field_type = introspection_module.DATA_TYPES_REVERSE[row[1]]
                 except KeyError:
