'Add a single filter to the query. The \'filter_expr\' is a pair:
(filter_string, value). E.g. (\'name__contains\', \'fred\')
If \'negate\' is True, this is an exclude() filter. It\'s important to
note that this method does not negate anything in the where-clause
object when inserting the filter constraints. This is because negated
filters often require multiple calls to add_filter() and the negation
should only happen once. So the caller is responsible for this (the
caller will normally be add_q(), so that as an example).
If \'trim\' is True, we automatically trim the final join group (used
internally when constructing nested queries).
If \'can_reuse\' is a set, we are processing a component of a
multi-component filter (e.g. filter(Q1, Q2)). In this case, \'can_reuse\'
will be a set of table aliases that can be reused in this filter, even
if we would otherwise force the creation of new aliases for a join
(needed for nested Q-filters). The set is updated by this method.
If \'process_extras\' is set, any extra filters returned from the table
joining process will be processed. This parameter is set to False
during the processing of extra filters to avoid infinite recursion.'

def add_filter(self, filter_expr, connector=AND, negate=False, trim=False, can_reuse=None, process_extras=True, force_having=False):

    (arg, value) = filter_expr
    parts = arg.split(LOOKUP_SEP)
    if (not parts):
        raise FieldError(('Cannot    parse    keyword    query    %r' % arg))
    if ((len(parts) == 1) or (parts[(-1)] not in self.query_terms)):
        lookup_type = 'exact'
    else:
        lookup_type = parts.pop()
    having_clause = False
    if (value is None):
        if (lookup_type != 'exact'):
            raise ValueError('Cannot    use    None    as    a    query    value')
        lookup_type = 'isnull'
        value = True
    elif callable(value):
        value = value()
    elif hasattr(value, 'evaluate'):
        value = SQLEvaluator(value, self)
        having_clause = value.contains_aggregate
    if (parts[0] in self.aggregates):
        aggregate = self.aggregates[parts[0]]
        entry = self.where_class()
        entry.add((aggregate, lookup_type, value), AND)
        if negate:
            entry.negate()
        self.having.add(entry, connector)
        return
    opts = self.get_meta()
    alias = self.get_initial_alias()
    allow_many = (trim or (not negate))
    try:
        (field, target, opts, join_list, last, extra_filters) = self.setup_joins(parts, opts, alias, True, allow_many, can_reuse=can_reuse, negate=negate, process_extras=process_extras)
    except MultiJoin as e:
        self.split_exclude(filter_expr, LOOKUP_SEP.join(parts[:e.level]), can_reuse)
        return
    if ((lookup_type == 'isnull') and (value is True) and (not negate) and (len(join_list) > 1)):
        self.promote_alias_chain(join_list)
    (col, alias, join_list) = self.trim_joins(target, join_list, last, trim)
    if (connector == OR):
        join_it = iter(join_list)
        table_it = iter(self.tables)
        (join_it.next(), table_it.next())
        table_promote = False
        join_promote = False
        for join in join_it:
            table = table_it.next()
            if ((join == table) and (self.alias_refcount[join] > 1)):
                continue
            join_promote = self.promote_alias(join)
            if (table != join):
                table_promote = self.promote_alias(table)
            break
        self.promote_alias_chain(join_it, join_promote)
        self.promote_alias_chain(table_it, table_promote)
    if (having_clause or force_having):
        if ((alias, col) not in self.group_by):
            self.group_by.append((alias, col))
        self.having.add((Constraint(alias, col, field), lookup_type, value), connector)
    else:
        self.where.add((Constraint(alias, col, field), lookup_type, value), connector)
    if negate:
        self.promote_alias_chain(join_list)
        if (lookup_type != 'isnull'):
            if (len(join_list) > 1):
                for alias in join_list:
                    if (self.alias_map[alias][JOIN_TYPE] == self.LOUTER):
                        j_col = self.alias_map[alias][RHS_JOIN_COL]
                        entry = self.where_class()
                        entry.add((Constraint(alias, j_col, None), 'isnull', True), AND)
                        entry.negate()
                        self.where.add(entry, AND)
                        break
            if ((not ((lookup_type == 'in') and (not hasattr(value, 'as_sql')) and (not hasattr(value, '_as_sql')) and (not value))) and field.null):
                self.where.add((Constraint(alias, col, None), 'isnull', False), AND)
    if (can_reuse is not None):
        can_reuse.update(join_list)
    if process_extras:
        for filter in extra_filters:
            self.add_filter(filter, negate=negate, can_reuse=can_reuse, process_extras=False)
