--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -460,6 +460,34 @@ class QuerySet(object):
         where.extend(where2)
         params.extend(params2)
 
+        # Resolve order_by dependencies before joins to order by related tables
+        order_by = []
+        if self._order_by is not None: # use order_by = () to disable ordering
+            ordering_to_use = self._order_by
+        else:
+            ordering_to_use = opts.ordering
+
+        for f in handle_legacy_orderlist(ordering_to_use):
+            if "." in f: # dot-style field, fall back to old ordering code below
+                order_by = []
+                break
+            elif f == '?': # Special case.
+                order_by.append(backend.get_random_function_sql())
+                break
+            elif f.startswith('-'):
+                path = f[1:].split(LOOKUP_SEPARATOR)
+                order = "DESC"
+            else:
+                path = f.split(LOOKUP_SEPARATOR)
+                order = "ASC"
+
+            joins3, where3, params3 = lookup_inner(path, 'exact', False, opts, opts.db_table, None)
+            joins.update(joins3)
+
+            # hack to get fieldname to order by. modify lookup_inner to supply this instead.
+            field = where3[0].replace(' = %s', '')
+            order_by.append('%s %s' % (field, order))
+
         # Add additional tables and WHERE clauses based on select_related.
         if self._select_related:
             fill_table_cache(opts, select, tables, where, opts.db_table, [opts.db_table])
@@ -485,32 +513,30 @@ class QuerySet(object):
             sql.append(where and "WHERE " + " AND ".join(where))
 
         # ORDER BY clause
-        order_by = []
         if self._order_by is not None:
             ordering_to_use = self._order_by
         else:
             ordering_to_use = opts.ordering
+        if order_by: # dont try to set up ordering again if already done
+            ordering_to_use = []
         for f in handle_legacy_orderlist(ordering_to_use):
-            if f == '?': # Special case.
-                order_by.append(backend.get_random_function_sql())
+            if f.startswith('-'):
+                col_name = f[1:]
+                order = "DESC"
             else:
-                if f.startswith('-'):
-                    col_name = f[1:]
-                    order = "DESC"
-                else:
-                    col_name = f
-                    order = "ASC"
-                if "." in col_name:
-                    table_prefix, col_name = col_name.split('.', 1)
-                    table_prefix = backend.quote_name(table_prefix) + '.'
+                col_name = f
+                order = "ASC"
+            if "." in col_name:
+                table_prefix, col_name = col_name.split('.', 1)
+                table_prefix = backend.quote_name(table_prefix) + '.'
+            else:
+                # Use the database table as a column prefix if it wasn't given,
+                # and if the requested column isn't a custom SELECT.
+                if "." not in col_name and col_name not in (self._select or ()):
+                    table_prefix = backend.quote_name(opts.db_table) + '.'
                 else:
-                    # Use the database table as a column prefix if it wasn't given,
-                    # and if the requested column isn't a custom SELECT.
-                    if "." not in col_name and col_name not in (self._select or ()):
-                        table_prefix = backend.quote_name(opts.db_table) + '.'
-                    else:
-                        table_prefix = ''
-                order_by.append('%s%s %s' % (table_prefix, backend.quote_name(orderfield2column(col_name, opts)), order))
+                    table_prefix = ''
+            order_by.append('%s%s %s' % (table_prefix, backend.quote_name(orderfield2column(col_name, opts)), order))
         if order_by:
             sql.append("ORDER BY " + ", ".join(order_by))
 
diff --git a/django/newforms/models.py b/django/newforms/models.py
index a938b63..dbcab14 100644
--- a/django/newforms/models.py
+++ b/django/newforms/models.py
@@ -33,7 +33,8 @@ def save_instance(form, instance, commit
     for f in opts.fields:
         if isinstance(f, models.AutoField):
             continue
-        setattr(instance, f.attname, clean_data[f.name])
+        if f.name in clean_data:
+            setattr(instance, f.attname, clean_data[f.name])
     if commit:
         instance.save()
         for f in opts.many_to_many:
diff --git a/tests/modeltests/ordering/models.py b/tests/modeltests/ordering/models.py
index 110ae3d..8fbcf83 100644
--- a/tests/modeltests/ordering/models.py
+++ b/tests/modeltests/ordering/models.py
@@ -11,6 +11,17 @@ The special-case field name ``"?"`` spec
 
 The ordering attribute is not required. If you leave it off, ordering will be
 undefined -- not random, just undefined.
+
+This also applies for models that have a relationship to another model, you
+can use the name of the related field just like you'd any other field to
+specify ordering of the model instances in the ``Meta.ordering`` attribute or
+the ``order_by`` queryset method.
+
+Another feature is that you can even order it by a field of the related model,
+for this you use a notation similar to the one used in field lookup, that is
+``relationname__fieldname`` (that's a double-underscore). This is only valid
+in the ``order_by`` queryset method, not in the ``Meta.ordering`` attribute
+though.
 """
 
 from django.db import models
@@ -24,6 +35,28 @@ class Article(models.Model):
     def __str__(self):
         return self.headline
 
+class ReaderLetter(models.Model):
+    article = models.ForeignKey(Article, null=True)
+    reader_name = models.CharField(maxlength=100)
+    class Meta:
+        #ordering = ('article_headline',)
+        ordering = ('reader_name',)
+
+    def __str__(self):
+    	if self.article is None:
+            return self.reader_name
+	else:
+            return "%s, %s" % (self.reader_name, self.article)
+
+class EditorResponse(models.Model):
+    reader_letter = models.ForeignKey(ReaderLetter)
+    editor_name = models.CharField(maxlength=100)
+    class Meta:
+        ordering = ('editor_name',)
+
+    def __str__(self):
+        return "%s, %s" % (self.editor_name, self.reader_letter)
+
 __test__ = {'API_TESTS':"""
 # Create a couple of Articles.
 >>> from datetime import datetime
@@ -64,4 +97,51 @@ # Use '?' to order randomly. (We're usin
 # don't know what order the output will be in.
 >>> Article.objects.order_by('?')
 [...]
+
+# Create some reader letters.
+# First the ones sent as comments about some article.
+>>> rl1 = ReaderLetter.objects.create(reader_name='Reader D', article=a1)
+>>> rl2 = ReaderLetter.objects.create(reader_name='Reader D', article=a2)
+>>> rl3 = ReaderLetter.objects.create(reader_name='Reader C', article=a4)
+>>> rl4 = ReaderLetter.objects.create(reader_name='Reader B', article=a4)
+>>> rl5 = ReaderLetter.objects.create(reader_name='Reader A', article=None)
+
+# By default ReaderLetter.objects.all() orders by the headline
+# of it's related article ascending.
+>>> ReaderLetter.objects.all()
+[<ReaderLetter: Reader A>, <ReaderLetter: Reader B, Article 4>, <ReaderLetter: Reader C, Article 4>, <ReaderLetter: Reader D, Article 1>, <ReaderLetter: Reader D, Article 2>]
+
+# Composite ordering using the related article headline descending as one of the components
+>>> ReaderLetter.objects.order_by('reader_name', '-article__headline')
+[<ReaderLetter: Reader B, Article 4>, <ReaderLetter: Reader C, Article 4>, <ReaderLetter: Reader D, Article 2>, <ReaderLetter: Reader D, Article 1>]
+
+>>> er1 = EditorResponse.objects.create(editor_name='Editor A', reader_letter=rl1)
+>>> er2 = EditorResponse.objects.create(editor_name='Editor B', reader_letter=rl2)
+>>> er3 = EditorResponse.objects.create(editor_name='Editor B', reader_letter=rl3)
+
+>>> EditorResponse.objects.all()
+[<EditorResponse: Editor A, Reader D, Article 1>, <EditorResponse: Editor B, Reader D, Article 2>, <EditorResponse: Editor B, Reader C, Article 4>]
+
+# Order by the PK of related ReaderLetter.
+>>> EditorResponse.objects.order_by('reader_letter')
+[<EditorResponse: Editor A, Reader D, Article 1>, <EditorResponse: Editor B, Reader D, Article 2>, <EditorResponse: Editor B, Reader C, Article 4>]
+
+# Order by another field of the related ReaderLetter object.
+>>> EditorResponse.objects.order_by('reader_letter__reader_name')
+[<EditorResponse: Editor B, Reader C, Article 4>, <EditorResponse: Editor A, Reader D, Article 1>, <EditorResponse: Editor B, Reader D, Article 2>]
+
+# The ordering specification can span models through relationships too.
+# Order by the PK of the article related to the reader letter related
+# to the editor response, descending.
+>>> EditorResponse.objects.order_by('-reader_letter__article')
+[<EditorResponse: Editor B, Reader C, Article 4>, <EditorResponse: Editor B, Reader D, Article 2>, <EditorResponse: Editor A, Reader D, Article 1>]
+
+# Order by the article publication date, ascending.
+>>> EditorResponse.objects.order_by('reader_letter__article__pub_date')
+[<EditorResponse: Editor A, Reader D, Article 1>, <EditorResponse: Editor B, Reader D, Article 2>, <EditorResponse: Editor B, Reader C, Article 4>]
+
+# Composite ordering with one of the components being a specification that
+# spans a FK relationship
+>>> EditorResponse.objects.order_by('-editor_name', 'reader_letter__article')
+[<EditorResponse: Editor B, Reader D, Article 2>, <EditorResponse: Editor B, Reader C, Article 4>, <EditorResponse: Editor A, Reader D, Article 1>]
 """}
