'Builds a WhereNode for a single filter clause, but doesn\'t add it
to this Query. Query.add_q() will then add this filter to the where
or having Node.
The \'branch_negated\' tells us if the current branch contains any
negations. This will be used to determine if subqueries are needed.
The \'current_negated\' is used to determine if the current filter is
negated or not and this will be used to determine if IS NULL filtering
is needed.
The difference between current_netageted and branch_negated is that
branch_negated is set on first negation, but current_negated is
flipped for each negation.
Note that add_filter will not do any negating itself, that is done
upper in the code by add_q().
The \'can_reuse\' is a set of reusable joins for multijoins.
The method will create a filter clause that can be added to the current
query. However, if the filter isn\'t added to the query then the caller
is responsible for unreffing the joins used.'

def build_filter(self, filter_expr, branch_negated=False, current_negated=False, can_reuse=None):

    (arg, value) = filter_expr
    parts = arg.split(LOOKUP_SEP)
    if (not parts):
        raise FieldError(('Cannot    parse    keyword    query    %r' % arg))
    lookup_type = 'exact'
    num_parts = len(parts)
    if ((len(parts) > 1) and (parts[(-1)] in self.query_terms) and (arg not in self.aggregates)):
        lookup_model = self.model
        for (counter, field_name) in enumerate(parts):
            try:
                lookup_field = lookup_model._meta.get_field(field_name)
            except FieldDoesNotExist:
                lookup_type = parts.pop()
                break
            if ((counter + 1) < num_parts):
                try:
                    lookup_model = lookup_field.rel.to
                except AttributeError:
                    lookup_type = parts.pop()
                    break
    clause = self.where_class()
    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 isinstance(value, ExpressionNode):
        value = SQLEvaluator(value, self, reuse=can_reuse)
    if (connections[DEFAULT_DB_ALIAS].features.interprets_empty_strings_as_nulls and (lookup_type == 'exact') and (value == '')):
        value = True
        lookup_type = 'isnull'
    for (alias, aggregate) in self.aggregates.items():
        if (alias in (parts[0], LOOKUP_SEP.join(parts))):
            clause.add((aggregate, lookup_type, value), AND)
            return clause
    opts = self.get_meta()
    alias = self.get_initial_alias()
    allow_many = (not branch_negated)
    try:
        (field, sources, opts, join_list, path) = self.setup_joins(parts, opts, alias, can_reuse, allow_many, allow_explicit_fk=True)
        if (can_reuse is not None):
            can_reuse.update(join_list)
        self._lookup_joins = join_list
    except MultiJoin as e:
        return self.split_exclude(filter_expr, LOOKUP_SEP.join(parts[:e.level]), can_reuse, e.names_with_path)
    if ((lookup_type == 'isnull') and (value is True) and (not current_negated) and (len(join_list) > 1)):
        self.promote_joins(join_list)
    (targets, alias, join_list) = self.trim_joins(sources, join_list, path)
    if hasattr(field, 'get_lookup_constraint'):
        constraint = field.get_lookup_constraint(self.where_class, alias, targets, sources, lookup_type, value)
    else:
        constraint = (Constraint(alias, targets[0].column, field), lookup_type, value)
    clause.add(constraint, AND)
    if (current_negated and ((lookup_type != 'isnull') or (value is False))):
        self.promote_joins(join_list)
        if ((lookup_type != 'isnull') and (self.is_nullable(targets[0]) or (self.alias_map[join_list[(-1)]].join_type == self.LOUTER))):
            clause.add((Constraint(alias, targets[0].column, None), 'isnull', False), AND)
    return clause
