Warnings on schema generation for FilterSets #7910

Closed
opened 2025-12-29 20:29:53 +01:00 by adam · 5 comments
Owner

Originally created by @amhn on GitHub (Apr 14, 2023).

NetBox version

v3.5-beta

Python version

3.10

Steps to Reproduce

Generate schema using, e.g.

./netbox/manage.py spectacular --color --file schema.json --validate --format openapi-json

Expected Behavior

No warnings are displayed.

Observed Behavior

Currently several warnings are displayed for filtersets:

/home/andy/python/netbox/netbox/ipam/filtersets.py:706: Warning [FHRPGroupViewSet > FHRPGroupFilterSet]: Unable to guess choice types from values, filter method's type hint or find "related_ip" in model. Defaulting to string.
/home/andy/python/netbox/netbox/ipam/filtersets.py:502: Warning [IPAddressViewSet > IPAddressFilterSet]: Unable to guess choice types from values, filter method's type hint or find "present_in_vrf_id" in model. Defaulting to string.
/home/andy/python/netbox/netbox/ipam/filtersets.py:502: Warning [IPAddressViewSet > IPAddressFilterSet]: Unable to guess choice types from values, filter method's type hint or find "present_in_vrf" in model. Defaulting to string.
Originally created by @amhn on GitHub (Apr 14, 2023). ### NetBox version v3.5-beta ### Python version 3.10 ### Steps to Reproduce Generate schema using, e.g. ``` ./netbox/manage.py spectacular --color --file schema.json --validate --format openapi-json ``` ### Expected Behavior No warnings are displayed. ### Observed Behavior Currently several warnings are displayed for filtersets: ``` /home/andy/python/netbox/netbox/ipam/filtersets.py:706: Warning [FHRPGroupViewSet > FHRPGroupFilterSet]: Unable to guess choice types from values, filter method's type hint or find "related_ip" in model. Defaulting to string. /home/andy/python/netbox/netbox/ipam/filtersets.py:502: Warning [IPAddressViewSet > IPAddressFilterSet]: Unable to guess choice types from values, filter method's type hint or find "present_in_vrf_id" in model. Defaulting to string. /home/andy/python/netbox/netbox/ipam/filtersets.py:502: Warning [IPAddressViewSet > IPAddressFilterSet]: Unable to guess choice types from values, filter method's type hint or find "present_in_vrf" in model. Defaulting to string. ```
adam added the status: needs ownerpending closuretype: housekeepingtopic: OpenAPI labels 2025-12-29 20:29:53 +01:00
adam closed this issue 2025-12-29 20:29:53 +01:00
Author
Owner

@amhn commented on GitHub (Apr 14, 2023):

drf-spectacular can not infer the parameter type for django_filters.ModelChoiceFilter fields. They should be added via extend_schema_field.

For present_in_vrf_id and present_in_vrf the annotation is added to the field directly to preserve the field description in the schema. The description is duplicated because once there is an override, no further introspection is done.

Possible diff:

diff --git a/netbox/ipam/filtersets.py b/netbox/ipam/filtersets.py
index a128b6acc..459f847d0 100644
--- a/netbox/ipam/filtersets.py
+++ b/netbox/ipam/filtersets.py
@@ -6,6 +6,9 @@ from django.db.models import Q
 from django.utils.translation import gettext as _
 from netaddr.core import AddrFormatError
 
+from drf_spectacular.utils import extend_schema_field
+from drf_spectacular.types import OpenApiTypes
+
 from dcim.models import Device, Interface, Region, Site, SiteGroup
 from netbox.filtersets import ChangeLoggedModelFilterSet, OrganizationalModelFilterSet, NetBoxModelFilterSet
 from tenancy.filtersets import TenancyFilterSet
@@ -284,17 +287,17 @@ class PrefixFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
         to_field_name='rd',
         label=_('VRF (RD)'),
     )
-    present_in_vrf_id = django_filters.ModelChoiceFilter(
+    present_in_vrf_id = extend_schema_field({'type': 'string', 'description': 'VRF'})(django_filters.ModelChoiceFilter(
         queryset=VRF.objects.all(),
         method='filter_present_in_vrf',
         label=_('VRF')
-    )
-    present_in_vrf = django_filters.ModelChoiceFilter(
+    ))
+    present_in_vrf = extend_schema_field({'type': 'string', 'description': 'VRF (RD)'})(django_filters.ModelChoiceFilter(
         queryset=VRF.objects.all(),
         method='filter_present_in_vrf',
         to_field_name='rd',
         label=_('VRF (RD)'),
-    )
+    ))
     region_id = TreeNodeMultipleChoiceFilter(
         queryset=Region.objects.all(),
         field_name='site__region',
@@ -526,17 +529,17 @@ class IPAddressFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
         to_field_name='rd',
         label=_('VRF (RD)'),
     )
-    present_in_vrf_id = django_filters.ModelChoiceFilter(
+    present_in_vrf_id = extend_schema_field({'type': 'string', 'description': 'VRF'})(django_filters.ModelChoiceFilter(
         queryset=VRF.objects.all(),
         method='filter_present_in_vrf',
         label=_('VRF')
-    )
-    present_in_vrf = django_filters.ModelChoiceFilter(
+    ))
+    present_in_vrf = extend_schema_field({'type': 'string', 'description': 'VRF (RD)'})(django_filters.ModelChoiceFilter(
         queryset=VRF.objects.all(),
         method='filter_present_in_vrf',
         to_field_name='rd',
         label=_('VRF (RD)'),
-    )
+    ))
     device = MultiValueCharFilter(
         method='filter_device',
         field_name='name',
@@ -727,6 +730,7 @@ class FHRPGroupFilterSet(NetBoxModelFilterSet):
             Q(name__icontains=value)
         )
 
+    @extend_schema_field(OpenApiTypes.STR)
     def filter_related_ip(self, queryset, name, value):
         """
         Filter by VRF & prefix of assigned IP addresses.
@@ -941,9 +945,11 @@ class VLANFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
             pass
         return queryset.filter(qs_filter)
 
+    @extend_schema_field(OpenApiTypes.STR)
     def get_for_device(self, queryset, name, value):
         return queryset.get_for_device(value)
 
+    @extend_schema_field(OpenApiTypes.STR)
     def get_for_virtualmachine(self, queryset, name, value):
         return queryset.get_for_virtualmachine(value)
@amhn commented on GitHub (Apr 14, 2023): drf-spectacular can not infer the parameter type for django_filters.ModelChoiceFilter fields. They should be added via extend_schema_field. For present_in_vrf_id and present_in_vrf the annotation is added to the field directly to preserve the field description in the schema. The description is duplicated because once there is an override, no further introspection is done. Possible diff: ```python diff --git a/netbox/ipam/filtersets.py b/netbox/ipam/filtersets.py index a128b6acc..459f847d0 100644 --- a/netbox/ipam/filtersets.py +++ b/netbox/ipam/filtersets.py @@ -6,6 +6,9 @@ from django.db.models import Q from django.utils.translation import gettext as _ from netaddr.core import AddrFormatError +from drf_spectacular.utils import extend_schema_field +from drf_spectacular.types import OpenApiTypes + from dcim.models import Device, Interface, Region, Site, SiteGroup from netbox.filtersets import ChangeLoggedModelFilterSet, OrganizationalModelFilterSet, NetBoxModelFilterSet from tenancy.filtersets import TenancyFilterSet @@ -284,17 +287,17 @@ class PrefixFilterSet(NetBoxModelFilterSet, TenancyFilterSet): to_field_name='rd', label=_('VRF (RD)'), ) - present_in_vrf_id = django_filters.ModelChoiceFilter( + present_in_vrf_id = extend_schema_field({'type': 'string', 'description': 'VRF'})(django_filters.ModelChoiceFilter( queryset=VRF.objects.all(), method='filter_present_in_vrf', label=_('VRF') - ) - present_in_vrf = django_filters.ModelChoiceFilter( + )) + present_in_vrf = extend_schema_field({'type': 'string', 'description': 'VRF (RD)'})(django_filters.ModelChoiceFilter( queryset=VRF.objects.all(), method='filter_present_in_vrf', to_field_name='rd', label=_('VRF (RD)'), - ) + )) region_id = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='site__region', @@ -526,17 +529,17 @@ class IPAddressFilterSet(NetBoxModelFilterSet, TenancyFilterSet): to_field_name='rd', label=_('VRF (RD)'), ) - present_in_vrf_id = django_filters.ModelChoiceFilter( + present_in_vrf_id = extend_schema_field({'type': 'string', 'description': 'VRF'})(django_filters.ModelChoiceFilter( queryset=VRF.objects.all(), method='filter_present_in_vrf', label=_('VRF') - ) - present_in_vrf = django_filters.ModelChoiceFilter( + )) + present_in_vrf = extend_schema_field({'type': 'string', 'description': 'VRF (RD)'})(django_filters.ModelChoiceFilter( queryset=VRF.objects.all(), method='filter_present_in_vrf', to_field_name='rd', label=_('VRF (RD)'), - ) + )) device = MultiValueCharFilter( method='filter_device', field_name='name', @@ -727,6 +730,7 @@ class FHRPGroupFilterSet(NetBoxModelFilterSet): Q(name__icontains=value) ) + @extend_schema_field(OpenApiTypes.STR) def filter_related_ip(self, queryset, name, value): """ Filter by VRF & prefix of assigned IP addresses. @@ -941,9 +945,11 @@ class VLANFilterSet(NetBoxModelFilterSet, TenancyFilterSet): pass return queryset.filter(qs_filter) + @extend_schema_field(OpenApiTypes.STR) def get_for_device(self, queryset, name, value): return queryset.get_for_device(value) + @extend_schema_field(OpenApiTypes.STR) def get_for_virtualmachine(self, queryset, name, value): return queryset.get_for_virtualmachine(value) ```
Author
Owner

@jeremystretch commented on GitHub (Jun 23, 2023):

Looks like @abhi1693 addressed most of these in #12987 but there's still at least one warning to address.

@jeremystretch commented on GitHub (Jun 23, 2023): Looks like @abhi1693 addressed most of these in #12987 but there's still at least one warning to address.
Author
Owner

@abhi1693 commented on GitHub (Aug 4, 2023):

The remaining warning is Warning [ServiceViewSet > ServiceFilterSet]: model field "IPAddressField" has no mapping in ModelSerializer. It may be a deprecated field. Defaulting to "string"

Here is a potential solution but I have not been able to get this working: https://github.com/tfranzel/drf-spectacular/issues/873#issuecomment-1331016036

@abhi1693 commented on GitHub (Aug 4, 2023): The remaining warning is `Warning [ServiceViewSet > ServiceFilterSet]: model field "IPAddressField" has no mapping in ModelSerializer. It may be a deprecated field. Defaulting to "string" ` Here is a potential solution but I have not been able to get this working: https://github.com/tfranzel/drf-spectacular/issues/873#issuecomment-1331016036
Author
Owner

@github-actions[bot] commented on GitHub (Nov 3, 2023):

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. NetBox is governed by a small group of core maintainers which means not all opened issues may receive direct feedback. Do not attempt to circumvent this process by "bumping" the issue; doing so will result in its immediate closure and you may be barred from participating in any future discussions. Please see our contributing guide.

@github-actions[bot] commented on GitHub (Nov 3, 2023): This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. NetBox is governed by a small group of core maintainers which means not all opened issues may receive direct feedback. **Do not** attempt to circumvent this process by "bumping" the issue; doing so will result in its immediate closure and you may be barred from participating in any future discussions. Please see our [contributing guide](https://github.com/netbox-community/netbox/blob/develop/CONTRIBUTING.md).
Author
Owner

@github-actions[bot] commented on GitHub (Dec 4, 2023):

This issue has been automatically closed due to lack of activity. In an effort to reduce noise, please do not comment any further. Note that the core maintainers may elect to reopen this issue at a later date if deemed necessary.

@github-actions[bot] commented on GitHub (Dec 4, 2023): This issue has been automatically closed due to lack of activity. In an effort to reduce noise, please do not comment any further. Note that the core maintainers may elect to reopen this issue at a later date if deemed necessary.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#7910