Beispiel #1
0
    def get_ordering(self):
        lookup_opts, params = self.lookup_opts, self.params
        # For ordering, first check the "ordering" parameter in the admin options,
        # then check the object's default ordering. If neither of those exist,
        # order descending by ID by default. Finally, look for manually-specified
        # ordering from the query string.
        ordering = lookup_opts.admin.ordering or lookup_opts.ordering or [
            '-' + lookup_opts.pk.name
        ]

        # Normalize it to new-style ordering.
        ordering = handle_legacy_orderlist(ordering)

        if ordering[0].startswith('-'):
            order_field, order_type = ordering[0][1:], 'desc'
        else:
            order_field, order_type = ordering[0], 'asc'
        if ORDER_VAR in params:
            try:
                field_name = lookup_opts.admin.list_display[int(
                    params[ORDER_VAR])]
                try:
                    f = lookup_opts.get_field(field_name)
                except models.FieldDoesNotExist:
                    # see if field_name is a name of a non-field
                    # that allows sorting
                    try:
                        attr = getattr(lookup_opts.admin.manager.model,
                                       field_name)
                        order_field = attr.admin_order_field
                    except AttributeError:
                        pass
                else:
                    if not isinstance(f.rel,
                                      models.ManyToOneRel) or not f.null:
                        order_field = f.name
            except (IndexError, ValueError):
                pass  # Invalid ordering specified. Just use the default.
        if ORDER_TYPE_VAR in params and params[ORDER_TYPE_VAR] in ('asc',
                                                                   'desc'):
            order_type = params[ORDER_TYPE_VAR]
        return order_field, order_type
Beispiel #2
0
    def get_ordering(self):
        lookup_opts, params = self.lookup_opts, self.params
        # For ordering, first check the "ordering" parameter in the admin options,
        # then check the object's default ordering. If neither of those exist,
        # order descending by ID by default. Finally, look for manually-specified
        # ordering from the query string.
        ordering = lookup_opts.admin.ordering or lookup_opts.ordering or ['-' + lookup_opts.pk.name]

        # Normalize it to new-style ordering.
        ordering = handle_legacy_orderlist(ordering)

        if ordering[0].startswith('-'):
            order_field, order_type = ordering[0][1:], 'desc'
        else:
            order_field, order_type = ordering[0], 'asc'
        if ORDER_VAR in params:
            try:
                field_name = lookup_opts.admin.list_display[int(params[ORDER_VAR])]
                try:
                    f = lookup_opts.get_field(field_name)
                except models.FieldDoesNotExist:
                    # see if field_name is a name of a non-field
                    # that allows sorting
                    try:
                        attr = getattr(lookup_opts.admin.manager.model, field_name)
                        order_field = attr.admin_order_field
                    except AttributeError:
                        pass
                else:
                    if not isinstance(f.rel, models.ManyToOneRel) or not f.null:
                        order_field = f.name
            except (IndexError, ValueError):
                pass # Invalid ordering specified. Just use the default.
        if ORDER_TYPE_VAR in params and params[ORDER_TYPE_VAR] in ('asc', 'desc'):
            order_type = params[ORDER_TYPE_VAR]
        return order_field, order_type
Beispiel #3
0
            def _get_sql_clause(self, get_full_query=False):
                from django.db.models.query import fill_table_cache, \
                    handle_legacy_orderlist, orderfield2column

                opts = self.model._meta
                qn = connection.ops.quote_name

                # Construct the fundamental parts of the query: SELECT X FROM Y WHERE Z.
                select = ["%s.%s" % (qn(opts.db_table), qn(f.column)) for f in opts.fields]
                tables = [quote_only_if_word(t) for t in self._tables]
                joins = SortedDict()
                where = self._where[:]
                params = self._params[:]

                # Convert self._filters into SQL.
                joins2, where2, params2 = self._filters.get_sql(opts)
                joins.update(joins2)
                where.extend(where2)
                params.extend(params2)

                # 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])

                # Add any additional SELECTs.
                if self._select:
                    select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), qn(s[0])) for s in self._select.items()])

                # Start composing the body of the SQL statement.
                sql = [" FROM", qn(opts.db_table)]

                # Compose the join dictionary into SQL describing the joins.
                if joins:
                    sql.append(" ".join(["%s %s %s ON %s" % (join_type, table, alias, condition)
                                    for (alias, (table, join_type, condition)) in joins.items()]))

                # Compose the tables clause into SQL.
                if tables:
                    sql.append(", " + ", ".join(tables))

                # Compose the where clause into SQL.
                if where:
                    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
                for f in handle_legacy_orderlist(ordering_to_use):
                    if f == '?': # Special case.
                        order_by.append(DatabaseOperations().random_function_sql())
                    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 = qn(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 = qn(opts.db_table) + '.'
                            else:
                                table_prefix = ''
                        order_by.append('%s%s %s' % (table_prefix, qn(orderfield2column(col_name, opts)), order))
                if order_by:
                    sql.append("ORDER BY " + ", ".join(order_by))

                # Look for column name collisions in the select elements
                # and fix them with an AS alias.  This allows us to do a
                # SELECT * later in the paging query.
                cols = [clause.split('.')[-1] for clause in select]
                for index, col in enumerate(cols):
                    if cols.count(col) > 1:
                        col = '%s%d' % (col.replace('"', ''), index)
                        cols[index] = col
                        select[index] = '%s AS %s' % (select[index], col)

                # LIMIT and OFFSET clauses
                # To support limits and offsets, Oracle requires some funky rewriting of an otherwise normal looking query.
                select_clause = ",".join(select)
                distinct = (self._distinct and "DISTINCT " or "")

                if order_by:
                    order_by_clause = " OVER (ORDER BY %s )" % (", ".join(order_by))
                else:
                    #Oracle's row_number() function always requires an order-by clause.
                    #So we need to define a default order-by, since none was provided.
                    order_by_clause = " OVER (ORDER BY %s.%s)" % \
                        (qn(opts.db_table), qn(opts.fields[0].db_column or opts.fields[0].column))
                # limit_and_offset_clause
                if self._limit is None:
                    assert self._offset is None, "'offset' is not allowed without 'limit'"

                if self._offset is not None:
                    offset = int(self._offset)
                else:
                    offset = 0
                if self._limit is not None:
                    limit = int(self._limit)
                else:
                    limit = None

                limit_and_offset_clause = ''
                if limit is not None:
                    limit_and_offset_clause = "WHERE rn > %s AND rn <= %s" % (offset, limit+offset)
                elif offset:
                    limit_and_offset_clause = "WHERE rn > %s" % (offset)

                if len(limit_and_offset_clause) > 0:
                    fmt = \
    """SELECT * FROM
      (SELECT %s%s,
              ROW_NUMBER()%s AS rn
       %s)
    %s"""
                    full_query = fmt % (distinct, select_clause,
                                        order_by_clause, ' '.join(sql).strip(),
                                        limit_and_offset_clause)
                else:
                    full_query = None

                if get_full_query:
                    return select, " ".join(sql), params, full_query
                else:
                    return select, " ".join(sql), params
Beispiel #4
0
            def _get_sql_clause(self, get_full_query=False):
                from django.db.models.query import fill_table_cache, \
                    handle_legacy_orderlist, orderfield2column

                opts = self.model._meta
                qn = connection.ops.quote_name

                # Construct the fundamental parts of the query: SELECT X FROM Y WHERE Z.
                select = [
                    "%s.%s" % (qn(opts.db_table), qn(f.column))
                    for f in opts.fields
                ]
                tables = [quote_only_if_word(t) for t in self._tables]
                joins = SortedDict()
                where = self._where[:]
                params = self._params[:]

                # Convert self._filters into SQL.
                joins2, where2, params2 = self._filters.get_sql(opts)
                joins.update(joins2)
                where.extend(where2)
                params.extend(params2)

                # 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])

                # Add any additional SELECTs.
                if self._select:
                    select.extend([
                        '(%s) AS %s' % (quote_only_if_word(s[1]), qn(s[0]))
                        for s in self._select.items()
                    ])

                # Start composing the body of the SQL statement.
                sql = [" FROM", qn(opts.db_table)]

                # Compose the join dictionary into SQL describing the joins.
                if joins:
                    sql.append(" ".join([
                        "%s %s %s ON %s" % (join_type, table, alias, condition)
                        for (alias, (table, join_type,
                                     condition)) in joins.items()
                    ]))

                # Compose the tables clause into SQL.
                if tables:
                    sql.append(", " + ", ".join(tables))

                # Compose the where clause into SQL.
                if where:
                    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
                for f in handle_legacy_orderlist(ordering_to_use):
                    if f == '?':  # Special case.
                        order_by.append(
                            DatabaseOperations().random_function_sql())
                    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 = qn(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 = qn(opts.db_table) + '.'
                            else:
                                table_prefix = ''
                        order_by.append(
                            '%s%s %s' %
                            (table_prefix, qn(orderfield2column(
                                col_name, opts)), order))
                if order_by:
                    sql.append("ORDER BY " + ", ".join(order_by))

                # Look for column name collisions in the select elements
                # and fix them with an AS alias.  This allows us to do a
                # SELECT * later in the paging query.
                cols = [clause.split('.')[-1] for clause in select]
                for index, col in enumerate(cols):
                    if cols.count(col) > 1:
                        col = '%s%d' % (col.replace('"', ''), index)
                        cols[index] = col
                        select[index] = '%s AS %s' % (select[index], col)

                # LIMIT and OFFSET clauses
                # To support limits and offsets, Oracle requires some funky rewriting of an otherwise normal looking query.
                select_clause = ",".join(select)
                distinct = (self._distinct and "DISTINCT " or "")

                if order_by:
                    order_by_clause = " OVER (ORDER BY %s )" % (
                        ", ".join(order_by))
                else:
                    #Oracle's row_number() function always requires an order-by clause.
                    #So we need to define a default order-by, since none was provided.
                    order_by_clause = " OVER (ORDER BY %s.%s)" % \
                        (qn(opts.db_table), qn(opts.fields[0].db_column or opts.fields[0].column))
                # limit_and_offset_clause
                if self._limit is None:
                    assert self._offset is None, "'offset' is not allowed without 'limit'"

                if self._offset is not None:
                    offset = int(self._offset)
                else:
                    offset = 0
                if self._limit is not None:
                    limit = int(self._limit)
                else:
                    limit = None

                limit_and_offset_clause = ''
                if limit is not None:
                    limit_and_offset_clause = "WHERE rn > %s AND rn <= %s" % (
                        offset, limit + offset)
                elif offset:
                    limit_and_offset_clause = "WHERE rn > %s" % (offset)

                if len(limit_and_offset_clause) > 0:
                    fmt = \
    """SELECT * FROM
      (SELECT %s%s,
              ROW_NUMBER()%s AS rn
       %s)
    %s"""
                    full_query = fmt % (distinct, select_clause,
                                        order_by_clause, ' '.join(sql).strip(),
                                        limit_and_offset_clause)
                else:
                    full_query = None

                if get_full_query:
                    return select, " ".join(sql), params, full_query
                else:
                    return select, " ".join(sql), params