'Adds a Q-object to the current filter.
Can also be used to add anything that has an \'add_to_query()\' method.'

def add_q(self, q_object, used_aliases=None, force_having=False):

    if (used_aliases is None):
        used_aliases = self.used_aliases
    if hasattr(q_object, 'add_to_query'):
        q_object.add_to_query(self, used_aliases)
    else:
        if (self.where and (q_object.connector != AND) and (len(q_object) > 1)):
            self.where.start_subtree(AND)
            subtree = True
        else:
            subtree = False
        connector = AND
        if ((q_object.connector == OR) and (not force_having)):
            force_having = self.need_force_having(q_object)
        for child in q_object.children:
            if (connector == OR):
                refcounts_before = self.alias_refcount.copy()
            if force_having:
                self.having.start_subtree(connector)
            else:
                self.where.start_subtree(connector)
            if isinstance(child, Node):
                self.add_q(child, used_aliases, force_having=force_having)
            else:
                self.add_filter(child, connector, q_object.negated, can_reuse=used_aliases, force_having=force_having)
            if force_having:
                self.having.end_subtree()
            else:
                self.where.end_subtree()
            if (connector == OR):
                self.promote_unused_aliases(refcounts_before, used_aliases)
            connector = q_object.connector
        if q_object.negated:
            self.where.negate()
        if subtree:
            self.where.end_subtree()
    if self.filter_is_sticky:
        self.used_aliases = used_aliases
