Пример #1
0
def get_model_siblings(Model, instance, queryset):
    pk = Model._meta.pk.name
    ordering = queryset.query.order_by

    if len(ordering) == 0 and len(Model._meta.ordering):
        ordering = Model._meta.ordering

    if not any(map(lambda x: x == pk or x == '-{}'.format(pk), ordering)):
        ordering = list(ordering) + ['-{}'.format(pk)]

    queryset.query.order_by = ordering
    compiler = SQLCompiler(queryset.query, connection, queryset.db)
    compiler.as_sql()

    join_sql, join_args = create_joins(queryset, compiler)
    where_sql, where_args = create_where(queryset, compiler)
    order_by_sql = create_order_by(compiler)

    row_number = get_row_number(Model, instance, join_sql, join_args,
                                where_sql, where_args, order_by_sql)

    if not row_number:
        return {}

    return get_row_siblings(Model, row_number, join_sql, join_args, where_sql,
                            where_args, order_by_sql)
Пример #2
0
    def get_triggers(self, using):
        if using:
            cconnection = connections[using]
        else:
            cconnection = connection

        qn = self.get_quote_name(using)

        related_field = self.manager.related.field
        if isinstance(related_field, ManyToManyField):
            fk_name = related_field.m2m_reverse_name()
            inc_where = [
                "%(id)s IN (SELECT %(reverse_related)s FROM %(m2m_table)s WHERE %(related)s = NEW.%(id)s)"
                % {
                    'id': qn(self.model._meta.pk.get_attname_column()[0]),
                    'related': qn(related_field.m2m_column_name()),
                    'm2m_table': qn(related_field.m2m_db_table()),
                    'reverse_related': qn(fk_name),
                }
            ]
            dec_where = [
                action.replace('NEW.', 'OLD.') for action in inc_where
            ]
        else:
            pk_name = qn(self.model._meta.pk.get_attname_column()[1])
            fk_name = qn(related_field.attname)
            inc_where = ["%s = NEW.%s" % (pk_name, fk_name)]
            dec_where = ["%s = OLD.%s" % (pk_name, fk_name)]

        content_type = str(ContentType.objects.get_for_model(self.model).pk)

        inc_query = TriggerFilterQuery(self.manager.related.model,
                                       trigger_alias='NEW')
        inc_query.add_q(Q(**self.filter))
        inc_query.add_q(~Q(**self.exclude))
        inc_filter_where, _ = inc_query.where.as_sql(
            SQLCompiler(inc_query, cconnection, using).quote_name_unless_alias,
            cconnection)

        dec_query = TriggerFilterQuery(self.manager.related.model,
                                       trigger_alias='OLD')
        dec_query.add_q(Q(**self.filter))
        dec_query.add_q(~Q(**self.exclude))
        dec_filter_where, where_params = dec_query.where.as_sql(
            SQLCompiler(dec_query, cconnection, using).quote_name_unless_alias,
            cconnection)

        if inc_filter_where:
            inc_where.append(inc_filter_where)
        if dec_filter_where:
            dec_where.append(dec_filter_where)
            # create the triggers for the incremental updates
        increment = triggers.TriggerActionUpdate(
            model=self.model,
            columns=(self.fieldname, ),
            values=(self.get_increment_value(using), ),
            where=(' AND '.join(inc_where), where_params),
        )
        decrement = triggers.TriggerActionUpdate(
            model=self.model,
            columns=(self.fieldname, ),
            values=(self.get_decrement_value(using), ),
            where=(' AND '.join(dec_where), where_params),
        )

        other_model = self.manager.related.model
        trigger_list = [
            triggers.Trigger(other_model, "after", "update",
                             [increment, decrement], content_type, using,
                             self.skip),
            triggers.Trigger(other_model, "after", "insert", [increment],
                             content_type, using, self.skip),
            triggers.Trigger(other_model, "after", "delete", [decrement],
                             content_type, using, self.skip),
        ]
        if isinstance(related_field, ManyToManyField):
            trigger_list.extend(
                self.m2m_triggers(content_type, fk_name, related_field, using))
        return trigger_list
Пример #3
0
 def get_compiler(self, using=None, connection=None):
     # Call super to figure out using and connection.
     c = super(TranslationQuery, self).get_compiler(using, connection)
     return SQLCompiler(self, c.connection, c.using)