示例#1
0
def _get_field(model, name):
    from django.db.models.fields import FieldDoesNotExist

    # Create a fake query object so we can easily work out what field
    # type we are dealing with
    qs = Query(model)
    opts = qs.get_meta()
    alias = qs.get_initial_alias()

    parts = name.split(LOOKUP_SEP)

    # The following is borrowed from the innards of Query.add_filter - it strips out __gt, __exact et al.
    num_parts = len(parts)
    if num_parts > 1 and parts[-1] in qs.query_terms:
        # Traverse the lookup query to distinguish related fields from
        # lookup types.
        for counter, field_name in enumerate(parts, 1):
            try:
                lookup_field = model._meta.get_field(field_name)
            except FieldDoesNotExist:
                # Not a field. Bail out.
                parts.pop()
                break
            # Unless we're at the end of the list of lookups, let's attempt
            # to continue traversing relations.
            if counter < num_parts:
                try:
                    model = lookup_field.rel.to
                except AttributeError:
                    # Not a related field. Bail out.
                    parts.pop()
                    break

    return resolve_field(qs, parts, opts, alias)
示例#2
0
 def test_filter_conditional(self):
     query = Query(Item)
     where = query.build_where(Func(output_field=BooleanField()))
     exact = where.children[0]
     self.assertIsInstance(exact, Exact)
     self.assertIsInstance(exact.lhs, Func)
     self.assertIs(exact.rhs, True)
示例#3
0
 def __init__(self, model, query=None, using=None):
     # the model needs to be defined so that we can construct our custom
     # query
     if query is None:
         query = Query(model)
         query.add_q(models.Q(effective_to__isnull=True))
     return super(ActiveQuerySet, self).__init__(model, query, using)
示例#4
0
    def resolve_lookup(self, model_cls: Type[Model], lookup: str) -> Field:
        query = Query(model_cls)
        lookup_parts, field_parts, is_expression = query.solve_lookup_type(
            lookup)
        if lookup_parts:
            raise FieldError('Lookups not supported yet')

        currently_observed_model = model_cls
        current_field = None
        for field_part in field_parts:
            if field_part == 'pk':
                return self.django_context.get_primary_key_field(
                    currently_observed_model)

            current_field = currently_observed_model._meta.get_field(
                field_part)
            if not isinstance(current_field, (ForeignObjectRel, RelatedField)):
                continue

            currently_observed_model = self.django_context.fields_context.get_related_model_cls(
                current_field)
            if isinstance(current_field, ForeignObjectRel):
                current_field = self.django_context.get_primary_key_field(
                    currently_observed_model)

        # if it is None, solve_lookup_type() will fail earlier
        assert current_field is not None
        return current_field
示例#5
0
 def __init__(self, model, query=None, using=None):
     # the model needs to be defined so that we can construct our custom
     # query
     if query is None:
         query = Query(model)
         query.add_q(models.Q(effective_to__isnull=True))
     return super(ActiveQuerySet, self).__init__(model, query, using)
示例#6
0
    def resolve_lookup_into_field(self, model_cls: Type[Model], lookup: str) -> Union[Field, ForeignObjectRel]:
        query = Query(model_cls)
        lookup_parts, field_parts, is_expression = query.solve_lookup_type(lookup)
        if lookup_parts:
            raise LookupsAreUnsupported()

        return self._resolve_field_from_parts(field_parts, model_cls)
示例#7
0
def _get_field(model, name):
    # Create a fake query object so we can easily work out what field
    # type we are dealing with
    qs = Query(model)
    parts = name.split(LOOKUP_SEP)

    # The following is borrowed from the innards of Query.add_filter - it strips out __gt, __exact et al.
    num_parts = len(parts)
    if num_parts > 1 and parts[-1] in QUERY_TERMS:
        # Traverse the lookup query to distinguish related fields from
        # lookup types.
        for counter, field_name in enumerate(parts, 1):
            try:
                lookup_field = model._meta.get_field(field_name)
            except FieldDoesNotExist:
                # Not a field. Bail out.
                parts.pop()
                break
            # Unless we're at the end of the list of lookups, let's attempt
            # to continue traversing relations.
            if counter < num_parts:
                try:
                    model = lookup_field.rel.to
                except AttributeError:
                    # Not a related field. Bail out.
                    parts.pop()
                    break

    return qs.names_to_path(parts, qs.get_meta(), True, fail_on_missing=False)[1]
示例#8
0
 def test_simple_query(self):
     query = Query(Author)
     where = query.build_where(Q(num__gt=2))
     lookup = where.children[0]
     self.assertIsInstance(lookup, GreaterThan)
     self.assertEqual(lookup.rhs, 2)
     self.assertEqual(lookup.lhs.target, Author._meta.get_field('num'))
示例#9
0
def _get_field(model, name):
    from django.db.models.fields import FieldDoesNotExist

    # Create a fake query object so we can easily work out what field
    # type we are dealing with
    qs = Query(model)
    opts = qs.get_meta()
    alias = qs.get_initial_alias()

    parts = name.split(LOOKUP_SEP)

    # The following is borrowed from the innards of Query.add_filter - it strips out __gt, __exact et al.
    num_parts = len(parts)
    if num_parts > 1 and parts[-1] in qs.query_terms:
        # Traverse the lookup query to distinguish related fields from
        # lookup types.
        for counter, field_name in enumerate(parts, 1):
            try:
                lookup_field = model._meta.get_field(field_name)
            except FieldDoesNotExist:
                # Not a field. Bail out.
                parts.pop()
                break
            # Unless we're at the end of the list of lookups, let's attempt
            # to continue traversing relations.
            if counter < num_parts:
                try:
                    model = lookup_field.rel.to
                except AttributeError:
                    # Not a related field. Bail out.
                    parts.pop()
                    break

    return resolve_field(qs, parts, opts, alias)
示例#10
0
def _get_field(model, name):

    # Create a fake query object so we can easily work out what field
    # type we are dealing with
    parts = name.split(LOOKUP_SEP)

    # The following is borrowed from the innards of Query.add_filter - it strips out __gt, __exact et al.
    num_parts = len(parts)
    if num_parts > 1 and parts[-1] in Query.query_terms:
        # Traverse the lookup query to distinguish related fields from
        # lookup types.
        for counter, field_name in enumerate(parts, 1):
            try:
                lookup_field = model._meta.get_field(field_name)
            except FieldDoesNotExist:
                # Not a field. Bail out.
                parts.pop()
                break
            # Unless we're at the end of the list of lookups, let's attempt
            # to continue traversing relations.
            if counter < num_parts:
                try:
                    model = lookup_field.rel.to
                except AttributeError:
                    # Not a related field. Bail out.
                    parts.pop()
                    break

    qs = Query(model)
    return qs.names_to_path(parts, qs.get_meta(), True,
                            fail_on_missing=False)[1]
示例#11
0
 def _get_condition_sql(self, model, schema_editor):
     if self.condition is None:
         return None
     query = Query(model=model)
     where = query.build_where(self.condition)
     compiler = query.get_compiler(connection=schema_editor.connection)
     sql, params = where.as_sql(compiler, schema_editor.connection)
     return sql % tuple(schema_editor.quote_value(p) for p in params)
示例#12
0
 def constraint_sql(self, model, schema_editor):
     query = Query(model)
     where = query.build_where(self.check)
     connection = schema_editor.connection
     compiler = connection.ops.compiler('SQLCompiler')(query, connection, 'default')
     sql, params = where.as_sql(compiler, connection)
     params = tuple(schema_editor.quote_value(p) for p in params)
     return schema_editor.sql_check_constraint % {'check': sql % params}
示例#13
0
 def _get_condition_sql(self, model, schema_editor):
     if self.condition is None:
         return None
     query = Query(model=model, alias_cols=False)
     where = query.build_where(self.condition)
     compiler = query.get_compiler(connection=schema_editor.connection)
     sql, params = where.as_sql(compiler, schema_editor.connection)
     return sql % tuple(schema_editor.quote_value(p) for p in params)
示例#14
0
 def test_multiple_fields(self):
     query = Query(Item)
     where = query.build_where(Q(modified__gt=F('created')))
     lookup = where.children[0]
     self.assertIsInstance(lookup, GreaterThan)
     self.assertIsInstance(lookup.rhs, SimpleCol)
     self.assertIsInstance(lookup.lhs, SimpleCol)
     self.assertEqual(lookup.rhs.target, Item._meta.get_field('created'))
     self.assertEqual(lookup.lhs.target, Item._meta.get_field('modified'))
示例#15
0
def follow_model_field_lookup(model, lookup):
    """
    Follow a model lookup `foreignkey__foreignkey__field` in the same
    way that Django QuerySet.filter() does, returning the final models.Field.
    """
    query = Query(model)
    lookup_splitted = lookup.split(LOOKUP_SEP)
    _, field, _, _ = query.names_to_path(lookup_splitted, query.get_meta())
    return field
示例#16
0
 def test_transform(self):
     query = Query(Author)
     with register_lookup(CharField, Lower):
         where = query.build_where(~Q(name__lower='foo'))
     lookup = where.children[0]
     self.assertIsInstance(lookup, Exact)
     self.assertIsInstance(lookup.lhs, Lower)
     self.assertIsInstance(lookup.lhs.lhs, SimpleCol)
     self.assertEqual(lookup.lhs.lhs.target, Author._meta.get_field('name'))
示例#17
0
 def test_q_annotation(self):
     query = Query(None)
     check = ExpressionWrapper(
         Q(RawSQL("%s IS NULL", (None, ), BooleanField()))
         | Q(Exists(Item.objects.all())),
         BooleanField(),
     )
     query.add_annotation(check, "_check")
     result = query.get_compiler(using=DEFAULT_DB_ALIAS).execute_sql(SINGLE)
     self.assertEqual(result[0], 1)
示例#18
0
 def test_negated_nullable(self):
     query = Query(Item)
     where = query.build_where(~Q(modified__lt=datetime(2017, 1, 1)))
     self.assertTrue(where.negated)
     lookup = where.children[0]
     self.assertIsInstance(lookup, LessThan)
     self.assertEqual(lookup.lhs.target, Item._meta.get_field('modified'))
     lookup = where.children[1]
     self.assertIsInstance(lookup, IsNull)
     self.assertEqual(lookup.lhs.target, Item._meta.get_field('modified'))
示例#19
0
 def test_names_to_path_field(self):
     query = Query(None)
     query.add_annotation(Value(True), "value")
     path, final_field, targets, names = query.names_to_path(["value"],
                                                             opts=None)
     self.assertEqual(path, [])
     self.assertIsInstance(final_field, BooleanField)
     self.assertEqual(len(targets), 1)
     self.assertIsInstance(targets[0], BooleanField)
     self.assertEqual(names, [])
示例#20
0
 def test_rawsql_annotation(self):
     query = Query(None)
     sql = "%s IS NULL"
     # Wrap with a CASE WHEN expression if a database backend (e.g. Oracle)
     # doesn't support boolean expression in SELECT list.
     if not connection.features.supports_boolean_expr_in_select_clause:
         sql = f"CASE WHEN {sql} THEN 1 ELSE 0 END"
     query.add_annotation(RawSQL(sql, (None, ), BooleanField()), "_check")
     result = query.get_compiler(using=DEFAULT_DB_ALIAS).execute_sql(SINGLE)
     self.assertEqual(result[0], 1)
示例#21
0
 def test_transform(self):
     query = Query(Author, alias_cols=False)
     with register_lookup(CharField, Lower):
         where = query.build_where(~Q(name__lower="foo"))
     lookup = where.children[0]
     self.assertIsInstance(lookup, Exact)
     self.assertIsInstance(lookup.lhs, Lower)
     self.assertIsInstance(lookup.lhs.lhs, Col)
     self.assertIsNone(lookup.lhs.lhs.alias)
     self.assertEqual(lookup.lhs.lhs.target, Author._meta.get_field("name"))
示例#22
0
 def test_foreign_key_exclusive(self):
     query = Query(ObjectC)
     where = query.build_where(Q(objecta=None) | Q(objectb=None))
     a_isnull = where.children[0]
     self.assertIsInstance(a_isnull, RelatedIsNull)
     self.assertIsInstance(a_isnull.lhs, SimpleCol)
     self.assertEqual(a_isnull.lhs.target, ObjectC._meta.get_field('objecta'))
     b_isnull = where.children[1]
     self.assertIsInstance(b_isnull, RelatedIsNull)
     self.assertIsInstance(b_isnull.lhs, SimpleCol)
     self.assertEqual(b_isnull.lhs.target, ObjectC._meta.get_field('objectb'))
示例#23
0
 def test_multiple_fields(self):
     query = Query(Item, alias_cols=False)
     where = query.build_where(Q(modified__gt=F("created")))
     lookup = where.children[0]
     self.assertIsInstance(lookup, GreaterThan)
     self.assertIsInstance(lookup.rhs, Col)
     self.assertIsNone(lookup.rhs.alias)
     self.assertIsInstance(lookup.lhs, Col)
     self.assertIsNone(lookup.lhs.alias)
     self.assertEqual(lookup.rhs.target, Item._meta.get_field("created"))
     self.assertEqual(lookup.lhs.target, Item._meta.get_field("modified"))
示例#24
0
    def resolve_lookup_expected_type(self, ctx: MethodContext,
                                     model_cls: Type[Model],
                                     lookup: str) -> MypyType:
        query = Query(model_cls)
        try:
            lookup_parts, field_parts, is_expression = query.solve_lookup_type(
                lookup)
            if is_expression:
                return AnyType(TypeOfAny.explicit)
        except FieldError as exc:
            ctx.api.fail(exc.args[0], ctx.context)
            return AnyType(TypeOfAny.from_error)

        field = self._resolve_field_from_parts(field_parts, model_cls)

        lookup_cls = None
        if lookup_parts:
            lookup = lookup_parts[-1]
            lookup_cls = field.get_lookup(lookup)
            if lookup_cls is None:
                # unknown lookup
                return AnyType(TypeOfAny.explicit)

        if lookup_cls is None or isinstance(lookup_cls, Exact):
            return self.get_field_lookup_exact_type(
                helpers.get_typechecker_api(ctx), field)

        assert lookup_cls is not None

        lookup_info = helpers.lookup_class_typeinfo(
            helpers.get_typechecker_api(ctx), lookup_cls)
        if lookup_info is None:
            return AnyType(TypeOfAny.explicit)

        for lookup_base in helpers.iter_bases(lookup_info):
            if lookup_base.args and isinstance(lookup_base.args[0], Instance):
                lookup_type: MypyType = lookup_base.args[0]
                # if it's Field, consider lookup_type a __get__ of current field
                if (isinstance(lookup_type, Instance)
                        and lookup_type.type.fullname()
                        == fullnames.FIELD_FULLNAME):
                    field_info = helpers.lookup_class_typeinfo(
                        helpers.get_typechecker_api(ctx), field.__class__)
                    if field_info is None:
                        return AnyType(TypeOfAny.explicit)
                    lookup_type = helpers.get_private_descriptor_type(
                        field_info,
                        '_pyi_private_get_type',
                        is_nullable=field.null)
                return lookup_type

        return AnyType(TypeOfAny.explicit)
示例#25
0
 def test_foreign_key_exclusive(self):
     query = Query(ObjectC, alias_cols=False)
     where = query.build_where(Q(objecta=None) | Q(objectb=None))
     a_isnull = where.children[0]
     self.assertIsInstance(a_isnull, RelatedIsNull)
     self.assertIsInstance(a_isnull.lhs, Col)
     self.assertIsNone(a_isnull.lhs.alias)
     self.assertEqual(a_isnull.lhs.target, ObjectC._meta.get_field("objecta"))
     b_isnull = where.children[1]
     self.assertIsInstance(b_isnull, RelatedIsNull)
     self.assertIsInstance(b_isnull.lhs, Col)
     self.assertIsNone(b_isnull.lhs.alias)
     self.assertEqual(b_isnull.lhs.target, ObjectC._meta.get_field("objectb"))
示例#26
0
    def test_simplecol_query(self):
        query = Query(Author)
        where = query.build_where(Q(num__gt=2, name__isnull=False) | Q(num__lt=F('id')))

        name_isnull_lookup, num_gt_lookup = where.children[0].children
        self.assertIsInstance(num_gt_lookup, GreaterThan)
        self.assertIsInstance(num_gt_lookup.lhs, SimpleCol)
        self.assertIsInstance(name_isnull_lookup, IsNull)
        self.assertIsInstance(name_isnull_lookup.lhs, SimpleCol)

        num_lt_lookup = where.children[1]
        self.assertIsInstance(num_lt_lookup, LessThan)
        self.assertIsInstance(num_lt_lookup.rhs, SimpleCol)
        self.assertIsInstance(num_lt_lookup.lhs, SimpleCol)
示例#27
0
    def test_simplecol_query(self):
        query = Query(Author)
        where = query.build_where(Q(num__gt=2, name__isnull=False) | Q(num__lt=F('id')))

        name_isnull_lookup, num_gt_lookup = where.children[0].children
        self.assertIsInstance(num_gt_lookup, GreaterThan)
        self.assertIsInstance(num_gt_lookup.lhs, SimpleCol)
        self.assertIsInstance(name_isnull_lookup, IsNull)
        self.assertIsInstance(name_isnull_lookup.lhs, SimpleCol)

        num_lt_lookup = where.children[1]
        self.assertIsInstance(num_lt_lookup, LessThan)
        self.assertIsInstance(num_lt_lookup.rhs, SimpleCol)
        self.assertIsInstance(num_lt_lookup.lhs, SimpleCol)
示例#28
0
    def test_complex_query(self):
        query = Query(Author)
        where = query.build_where(Q(num__gt=2) | Q(num__lt=0))
        self.assertEqual(where.connector, OR)

        lookup = where.children[0]
        self.assertIsInstance(lookup, GreaterThan)
        self.assertEqual(lookup.rhs, 2)
        self.assertEqual(lookup.lhs.target, Author._meta.get_field('num'))

        lookup = where.children[1]
        self.assertIsInstance(lookup, LessThan)
        self.assertEqual(lookup.rhs, 0)
        self.assertEqual(lookup.lhs.target, Author._meta.get_field('num'))
示例#29
0
    def get_related_decrement_value(self, using):
        qn = self.get_quote_name(using)

        related_query = Query(self.manager.related.model)
        related_query.add_extra(None, None, [
            "%s = %s.%s" %
            (qn(self.model._meta.pk.get_attname_column()[1]), 'OLD',
             qn(self.manager.related.field.m2m_column_name()))
        ], None, None, None)
        related_query.add_fields([self.fieldname])
        related_query.clear_ordering(force_empty=True)
        related_query.default_cols = False
        related_filter_where, related_where_params = related_query.get_compiler(
            using=using).as_sql()
        return "%s - (%s)" % (qn(self.fieldname), related_filter_where)
示例#30
0
    def get_related_decrement_value(self, using):
        qn = self.get_quote_name(using)

        related_query = Query(self.manager.related.model)
        related_query.add_extra(None, None,
            ["%s = %s.%s" % (qn(self.model._meta.pk.get_attname_column()[1]), 'OLD', qn(self.manager.related.field.m2m_column_name()))],
            None, None, None)
        related_query.add_fields([self.fieldname])
        related_query.clear_ordering(force_empty=True)
        related_query.default_cols = False
        related_filter_where, related_where_params = related_query.get_compiler(using=using).as_sql()
        return "%s - (%s)" % (qn(self.fieldname), related_filter_where)
示例#31
0
    def test_non_alias_cols_query(self):
        query = Query(Author, alias_cols=False)
        where = query.build_where(Q(num__gt=2, name__isnull=False) | Q(num__lt=F("id")))

        name_isnull_lookup, num_gt_lookup = where.children[0].children
        self.assertIsInstance(num_gt_lookup, GreaterThan)
        self.assertIsInstance(num_gt_lookup.lhs, Col)
        self.assertIsNone(num_gt_lookup.lhs.alias)
        self.assertIsInstance(name_isnull_lookup, IsNull)
        self.assertIsInstance(name_isnull_lookup.lhs, Col)
        self.assertIsNone(name_isnull_lookup.lhs.alias)

        num_lt_lookup = where.children[1]
        self.assertIsInstance(num_lt_lookup, LessThan)
        self.assertIsInstance(num_lt_lookup.rhs, Col)
        self.assertIsNone(num_lt_lookup.rhs.alias)
        self.assertIsInstance(num_lt_lookup.lhs, Col)
        self.assertIsNone(num_lt_lookup.lhs.alias)
示例#32
0
 def _get_index_expressions(self, model, schema_editor):
     if not self.expressions:
         return None
     index_expressions = []
     for expression in self.expressions:
         index_expression = IndexExpression(expression)
         index_expression.set_wrapper_classes(schema_editor.connection)
         index_expressions.append(index_expression)
     return ExpressionList(*index_expressions).resolve_expression(
         Query(model, alias_cols=False), )
    def test_PGCRYPT_KEY_setting_per_database_decrypt(self, db, model, vals):
        conn = connections['secondary']
        obj = model(value=vals[0])
        field = obj._meta.get_field('value')
        col = field.get_col(obj._meta.db_table)
        query = Query(model)
        compiler = SQLInsertCompiler(query, conn, 'secondary')
        sql, params = col.as_sql(compiler, conn)

        assert 'secondary_key' in sql
示例#34
0
def _get_field(model, name):
    if django.VERSION[0] >= 1 and django.VERSION[1] >= 8:
        # Django 1.8+ - can use something like 
        # expression.output_field.get_internal_field() == 'Money..'
        raise NotImplementedError("Django 1.8+ support is not implemented.")

    from django.db.models.fields import FieldDoesNotExist

    # Create a fake query object so we can easily work out what field
    # type we are dealing with
    qs = Query(model)
    opts = qs.get_meta()
    alias = qs.get_initial_alias()

    parts = name.split(LOOKUP_SEP)

    # The following is borrowed from the innards of Query.add_filter - it strips out __gt, __exact et al.
    num_parts = len(parts)
    if num_parts > 1 and parts[-1] in qs.query_terms:
        # Traverse the lookup query to distinguish related fields from
        # lookup types.
        lookup_model = model
        for counter, field_name in enumerate(parts):
            try:
                lookup_field = lookup_model._meta.get_field(field_name)
            except FieldDoesNotExist:
                # Not a field. Bail out.
                parts.pop()
                break
            # Unless we're at the end of the list of lookups, let's attempt
            # to continue traversing relations.
            if (counter + 1) < num_parts:
                try:
                    lookup_model = lookup_field.rel.to
                except AttributeError:
                    # Not a related field. Bail out.
                    parts.pop()
                    break

    if django.VERSION[0] >= 1 and django.VERSION[1] in (6, 7):
        # Django 1.6-1.7
        field = qs.setup_joins(parts, opts, alias)[0]
    else:
        # Django 1.4-1.5
        field = qs.setup_joins(parts, opts, alias, False)[0]

    return field
示例#35
0
 def test_foreign_key_f(self):
     query = Query(Ranking)
     with self.assertRaises(FieldError):
         query.build_where(Q(rank__gt=F('author__num')))
示例#36
0
    def get_related_where(self, fk_name, using, type):
        qn = self.get_quote_name(using)

        related_where = ["%s = %s.%s" % (qn(self.model._meta.pk.get_attname_column()[1]), type, qn(fk_name))]
        related_query = Query(self.manager.related.model)
        for name, value in self.filter.iteritems():
            related_query.add_q(Q(**{name: value}))
        for name, value in self.exclude.iteritems():
            related_query.add_q(~Q(**{name: value}))
        related_query.add_extra(None, None,
            ["%s = %s.%s" % (qn(self.model._meta.pk.get_attname_column()[1]), type, qn(self.manager.related.field.m2m_column_name()))],
            None, None, None)
        related_query.add_count_column()
        related_query.clear_ordering(force_empty=True)
        related_query.default_cols = False
        related_filter_where, related_where_params = related_query.get_compiler(using=using).as_sql()
        if related_filter_where is not None:
            related_where.append('(' + related_filter_where + ') > 0')
        return related_where, related_where_params
示例#37
0
 def test_foreign_key(self):
     query = Query(Item)
     msg = 'Joined field references are not permitted in this query'
     with self.assertRaisesMessage(FieldError, msg):
         query.build_where(Q(creator__num__gt=2))