Fixes #639: Respect filter_logic in generated filtersets - #644
Conversation
CustomObjectTypeField.filter_logic has existed since the plugin's
earliest commits but was never actually read by filterset generation.
build_filter_for_field() always built the base text/longtext/url
filter with a hardcoded lookup_expr="icontains", regardless of what
filter_logic was set to.
This silently broke suffix lookups (e.g. ?f1__isw=foo, ?f1__iew=foo,
?f1__ic=foo): BaseFilterSet.get_additional_lookups() only augments a
filter whose own lookup_expr is one of a small fixed set ('exact',
'iexact', 'in', 'contains') -- "icontains" is not among them -- so
those suffix filters were never registered at all, and the
unrecognized query param was silently ignored, returning every row
unfiltered instead of raising an error or filtering correctly.
Fix mirrors NetBox core's own CustomField.to_filter() convention
exactly, since this plugin's filter_logic field was modeled on it in
the first place:
- "loose" (the default): base filter keeps using icontains, unchanged
from current behavior.
- "exact": drops the lookup_expr override (CharFilter's own default is
"exact"), which is what makes the base filter eligible for
get_additional_lookups() to generate the __n/__ic/__isw/__iew/__ie/
__empty/__regex suffix filters.
- "disabled": skip building a filter for the field entirely, matching
NetBox core's own universal (type-agnostic) skip for disabled custom
fields. This was also silently ignored before; now it does what the
UI has always documented it as doing.
Applies to TYPE_TEXT, TYPE_LONGTEXT, and TYPE_URL -- the same three
types NetBox core's own filter_logic switch covers. TYPE_JSON keeps
its existing icontains-only behavior (no core-NetBox "exact" analog to
mirror).
The comment/docstring volume grew into reviewer-facing rationale rather than concise code documentation -- restating the same mechanism (icontains falling outside get_additional_lookups fixed lookup set) at both the constant definition and its usage site, and a 14-line class docstring duplicating what the individual test method names and bodies already convey. Trimmed to the load-bearing parts.
|
@claude /review - report only on potential concerns. |
|
Claude finished @bctiemann's task in 1m 23s —— View job PR Review: Closes #639 — Respect filter_logic in generated filtersets
Three potential concerns: 1.
if field.filter_logic == CustomFieldFilterLogicChoices.FILTER_EXACT:
extra_kwargs["lookup_expr"] = None
2. Disabled fields still participate in the global
for field in model.custom_object_type.fields.all():
if field.type in [TYPE_TEXT, TYPE_LONGTEXT, TYPE_JSON, TYPE_URL, ...]:
q |= Q(**{f"{field.name}__icontains": value})There is no 3. No filter_logic test coverage for
None of these are blocking — concerns 2 and 3 are gaps to document or follow up on rather than bugs in the implemented fix. |
Fixes: #639
Summary
Test plan