Example #1
0
    def create_query(self, parent_context: Optional[QueryContext]) -> QueryBuilder:
        query = self.query_builder(parent_context.alias if parent_context else None)
        context = QueryContext(query, parent_context)
        context.push(self.model, query._from[-1])
        self._add_query_details(context=context)
        context.query._delete_from = True
        context.pop()

        return context.query
Example #2
0
    def _resolve_filter(self, queryset: "AwaitableStatement[MODEL]", context: QueryContext, key, value) -> QueryClauses:
        context_item = context.top
        model = context_item.model
        table = context_item.table

        if value is None and "isnull" in model._meta.db.filter_class.FILTER_FUNC_MAP:
            value = True
            key = f"{key}{LOOKUP_SEP}isnull"

        relation_field_name, _, field_sub = key.partition(LOOKUP_SEP)
        if self._check_annotations and relation_field_name in queryset.annotations:
            (filter_operator, _) = model._meta.db.filter_class.FILTER_FUNC_MAP[field_sub]
            annotation = queryset.annotations[relation_field_name]
            if annotation.field.is_aggregate:
                return QueryClauses(having_criterion=filter_operator(annotation.field, value))
            else:
                return QueryClauses(where_criterion=filter_operator(annotation.field, value))

        field_object = model._meta.fields_map.get(relation_field_name)
        if not field_object:
            raise UnknownFieldError(relation_field_name, model)

        key_filter = model._meta.get_filter(key)
        if key_filter:
            if isinstance(field_object, RelationField):
                join_data = context.join_table_by_field(table, field_object, full=False)
                if join_data:
                    #
                    # We are potentially adding two None here into the context
                    # however, since we have a valid key_filter it means no sub_field
                    # and hence to inner tables and no context is necessary, except
                    # for the correct position of the stack levels,
                    #
                    context.push(join_data.model, join_data.table)
                    clauses = QueryClauses(where_criterion=key_filter(context, value))
                    context.pop()
                else:
                    clauses = QueryClauses(where_criterion=key_filter(context, value))

                return clauses

            else:
                return QueryClauses(where_criterion=key_filter(context, value))

        if isinstance(field_object, RelationField):
            join_data = context.join_table_by_field(table, field_object)
            context.push(join_data.model, join_data.table)

            q = Q(**{field_sub: value})
            q._check_annotations = False
            modifier = q._resolve(queryset=queryset, context=context)
            context.pop()

            return modifier

        raise BaseFieldError(key, model)
Example #3
0
    def create_query_context(self, parent_context: Optional[QueryContext]) -> QueryContext:
        query = self.query_builder(parent_context.alias if parent_context else None)\
            .select(*self.model._meta.db_columns)

        context = QueryContext(query, parent_context)
        context.push(self.model, query._from[-1])
        context.resolve_select_related(self._select_related)
        context.pop()

        return context
Example #4
0
    def create_query(self, parent_context: QueryContext) -> QueryBuilder:
        query = self.query_builder(
            parent_context.alias if parent_context else None)
        context = QueryContext(query, parent_context)
        context.push(self.model, query._from[-1])

        self._add_query_details(context=context)
        for return_as, field_name in self.fields_for_select.items():
            _, field = context.resolve_field_name(field_name,
                                                  self,
                                                  accept_relation=False)
            context.query._select_other(field.as_(return_as))

        context.pop()
        return context.query
Example #5
0
    def create_query(self, parent_context: Optional[QueryContext]) -> QueryBuilder:

        db_client = self._get_db_client()
        table = self.model._meta.table(parent_context.alias if parent_context else None)

        context = QueryContext(query=db_client.query_class.update(table), parent_context=parent_context)
        context.push(self.model, table)
        self._add_query_details(context=context)

        for field_name, value in self.update_kwargs.items():
            field_object = self.model._meta.fields_map.get(field_name)

            if not field_object:
                raise UnknownFieldError(field_name, self.model)

            if field_object.primary_key:
                raise IntegrityError(f"Field {field_name} is primary key and can not be updated")

            if isinstance(field_object, RelationField):
                if isinstance(field_object, (ForeignKey, OneToOneField)):
                    fk_field_name: str = field_object.id_field_name
                    fk_field_object = self.model._meta.fields_map[fk_field_name]
                    value = fk_field_object.db_value(value.pk, None)
                    context.query = context.query.set(fk_field_object.db_column, value)

                else:
                    raise NotADbColumnFieldError(field_name, self.model)

            else:
                if isinstance(value, Term):
                    value = TermAnnotation(value)
                    value.resolve_into(self, context)
                    value = value.field

                elif isinstance(value, Annotation):
                    value.resolve_into(self, context)
                    value = value.field

                else:
                    value = field_object.db_value(value, None)

                context.query = context.query.set(field_object.db_column, value)

        context.pop()
        return context.query