def find_ordering_name(self, name, opts, alias=None, default_order='ASC', already_seen=None):
    "\n        Returns the table alias (the name might be ambiguous, the alias will\n        not be) and column name for ordering by the given 'name' parameter.\n        The 'name' is of the form 'field1__field2__...__fieldN'.\n        "
    (name, order) = get_order_dir(name, default_order)
    descending = (True if (order == 'DESC') else False)
    pieces = name.split(LOOKUP_SEP)
    (field, targets, alias, joins, path, opts) = self._setup_joins(pieces, opts, alias)
    if (field.is_relation and path and opts.ordering and (name != field.attname)):
        if (not already_seen):
            already_seen = set()
        join_tuple = tuple((getattr(self.query.alias_map[j], 'join_cols', None) for j in joins))
        if (join_tuple in already_seen):
            raise FieldError('Infinite loop caused by ordering.')
        already_seen.add(join_tuple)
        results = []
        for item in opts.ordering:
            results.extend(self.find_ordering_name(item, opts, alias, order, already_seen))
        return results
    (targets, alias, _) = self.query.trim_joins(targets, joins, path)
    return [(OrderBy(t.get_col(alias), descending=descending), False) for t in targets]
Returns the table alias (the name might be ambiguous, the alias will
not be) and column name for ordering by the given 'name' parameter.
The 'name' is of the form 'field1__field2__...__fieldN'.
def find_ordering_name(self, name, opts, alias=None, default_order='ASC', already_seen=None):
    "\n        Returns the table alias (the name might be ambiguous, the alias will\n        not be) and column name for ordering by the given 'name' parameter.\n        The 'name' is of the form 'field1__field2__...__fieldN'.\n        "
    (name, order) = get_order_dir(name, default_order)
    descending = (True if (order == 'DESC') else False)
    pieces = name.split(LOOKUP_SEP)
    (field, targets, alias, joins, path, opts) = self._setup_joins(pieces, opts, alias)
    if (field.is_relation and path and opts.ordering and (name != field.attname)):
        if (not already_seen):
            already_seen = set()
        join_tuple = tuple((getattr(self.query.alias_map[j], 'join_cols', None) for j in joins))
        if (join_tuple in already_seen):
            raise FieldError('Infinite loop caused by ordering.')
        already_seen.add(join_tuple)
        results = []
        for item in opts.ordering:
            results.extend(self.find_ordering_name(item, opts, alias, order, already_seen))
        return results
    (targets, alias, _) = self.query.trim_joins(targets, joins, path)
    return [(OrderBy(t.get_col(alias), descending=descending), False) for t in targets]