--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -446,6 +446,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])
@@ -471,32 +499,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))
 
--- a/django/newforms/models.py
+++ b/django/newforms/models.py
@@ -36,7 +36,8 @@ def save_instance(form, instance, commit
     for f in opts.fields + opts.many_to_many:
         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()
     return instance
