296 custom type object dynamic fields filter#365
296 custom type object dynamic fields filter#365ifoughal wants to merge 13 commits intonetboxlabs:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This pull request adds dynamic filtering capabilities for custom object type fields, allowing users to filter custom objects based on their field values. The changes introduce a flexible filter specification system that maps each custom field type to an appropriate django-filter Filter class.
Changes:
- Introduced a
FilterSpecdataclass and field type-to-filter mapping system in filtersets.py - Added
build_filter_for_fieldfunction to dynamically generate filters for custom fields - Implemented
get_filterform_fieldmethods for Object and MultiObject field types in field_types.py - Changed decimal field precision from 2 to 4 decimal places
- Fixed incorrect module name from "database.filtersets" to "netbox_custom_objects.filtersets"
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| netbox_custom_objects/filtersets.py | Adds FilterSpec dataclass, FIELD_TYPE_FILTERS mapping, and build_filter_for_field function to dynamically create filters for custom fields; fixes module name bug |
| netbox_custom_objects/field_types.py | Implements get_filterform_field methods for DecimalFieldType, ObjectFieldType, and MultiObjectFieldType; increases decimal precision from 2 to 4 places |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Apply defaults from the spec | ||
| if self.extra_kwargs: | ||
| filter_kwargs.update(self.extra_kwargs) |
There was a problem hiding this comment.
In the build method, line 47 updates filter_kwargs with self.extra_kwargs, which may contain unresolved lambda functions (e.g., {"choices": lambda f: f.choices}). Although these lambdas are intended to be overridden by the resolved values passed in **kwargs at line 50, if a caller forgets to resolve and pass them, the lambda will be passed directly to the Filter constructor, causing an error. Consider either removing line 47 entirely since the resolved values come through kwargs, or adding a check to ensure no callables remain in self.extra_kwargs when used.
| # Apply defaults from the spec | |
| if self.extra_kwargs: | |
| filter_kwargs.update(self.extra_kwargs) | |
| # Apply defaults from the spec, but avoid passing unresolved callables | |
| if self.extra_kwargs: | |
| for key, value in self.extra_kwargs.items(): | |
| if callable(value): | |
| continue | |
| filter_kwargs.setdefault(key, value) |
arthanson
left a comment
There was a problem hiding this comment.
Couple simple changes, could you also add some simple test cases for filtering, maybe create a field of each type, create records with the different types then do a filter on each type that checks the correct instance is returned.
|
|
||
| def get_filterform_field(self, field, **kwargs): | ||
| return None | ||
| """ |
There was a problem hiding this comment.
Can probably move this and the one above in ObjectFieldType to a new base class mixin, bit better for DRY.
|
|
||
|
|
||
| def build_filter_for_field(field) -> Optional[django_filters.Filter]: | ||
| spec = FIELD_TYPE_FILTERS.get(field.type) |
There was a problem hiding this comment.
can simplify:
if not (spec := FIELD_TYPE_FILTERS.get(field.type)):
return None
arthanson
left a comment
There was a problem hiding this comment.
Please see previous comments.
|
@ifoughal any updates on this? See my latest comments. |
@arthanson apologies, i didn't have much time lately to work on this. I'll get back on it as soon as I get some bandwidth. |
closes #296