'Build a WhereNode for a single filter clause but don\'t add it
to this Query. Query.add_q() will then add this filter to the where
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_negated 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, allow_joins=True, split_subq=True):

    if isinstance(filter_expr, dict):
        raise FieldError('Cannot    parse    keyword    query    as    dict')
    (arg, value) = filter_expr
    if (not arg):
        raise FieldError(('Cannot    parse    keyword    query    %r' % arg))
    (lookups, parts, reffed_expression) = self.solve_lookup_type(arg)
    if ((not allow_joins) and (len(parts) > 1)):
        raise FieldError('Joined    field    references    are    not    permitted    in    this    query')
    (value, used_joins) = self.resolve_lookup_value(value, can_reuse, allow_joins)
    clause = self.where_class()
    if reffed_expression:
        condition = self.build_lookup(lookups, reffed_expression, value)
        clause.add(condition, AND)
        return (clause, [])
    opts = self.get_meta()
    alias = self.get_initial_alias()
    allow_many = ((not branch_negated) or (not split_subq))
    try:
        join_info = self.setup_joins(parts, opts, alias, can_reuse=can_reuse, allow_many=allow_many)
        if isinstance(value, Iterator):
            value = list(value)
        self.check_related_objects(join_info.final_field, value, join_info.opts)
        self._lookup_joins = join_info.joins
    except MultiJoin as e:
        return self.split_exclude(filter_expr, LOOKUP_SEP.join(parts[:e.level]), can_reuse, e.names_with_path)
    used_joins.update(join_info.joins)
    (targets, alias, join_list) = self.trim_joins(join_info.targets, join_info.joins, join_info.path)
    if (can_reuse is not None):
        can_reuse.update(join_list)
    if join_info.final_field.is_relation:
        num_lookups = len(lookups)
        if (num_lookups > 1):
            raise FieldError('Related    Field    got    invalid    lookup:    {}'.format(lookups[0]))
        if (len(targets) == 1):
            col = targets[0].get_col(alias, join_info.final_field)
        else:
            col = MultiColSource(alias, targets, join_info.targets, join_info.final_field)
    else:
        col = targets[0].get_col(alias, join_info.final_field)
    condition = self.build_lookup(lookups, col, value)
    lookup_type = condition.lookup_name
    clause.add(condition, AND)
    require_outer = ((lookup_type == 'isnull') and (condition.rhs is True) and (not current_negated))
    if (current_negated and ((lookup_type != 'isnull') or (condition.rhs is False))):
        require_outer = True
        if ((lookup_type != 'isnull') and (self.is_nullable(targets[0]) or (self.alias_map[join_list[(-1)]].join_type == LOUTER))):
            lookup_class = targets[0].get_lookup('isnull')
            clause.add(lookup_class(targets[0].get_col(alias, join_info.targets[0]), False), AND)
    return (clause, (used_joins if (not require_outer) else ()))
