Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API Schema generating wrong if SuffixedMultiWidget overriden #1351

Open
DoubleTroubleOf opened this issue Dec 10, 2024 · 1 comment
Open

Comments

@DoubleTroubleOf
Copy link

DoubleTroubleOf commented Dec 10, 2024

Describe the bug
Parameter inspector for DRF views is ignoring the format of lookup described in overriden widget.

For example I've overrided the RangeFilter (django_filters.widgets.RangeWidget) so it started using __ (double underscore) as a separator for field_name and suffixes (min/max).
Generally it reproduces with any filters that are using widgets inherited from django_filters.widgets.SuffixedMultiWidget

The issues is that filters are parsed properly from received request with double underscore passed as separator, but API schema is wrong. Schema still generating with single underscore separator

I've debuged this issue and discovered issue inside drf_spectacular.contrib.django_filters.py:DjangoFilterExtension.resolve_filter_field method. Here is permalink.
I think it's better to use widget().suffixed() method here, instead hardcoded separator

Dependencies versions:

  • Django==5.0.4
  • djangorestframework==3.15.1
  • django-filter==24.2
  • drf-spectacular==0.27.2

To Reproduce

  1. Set up filterset to use custom Filter, field_class and widget. Here is short sample of custom changes
# models.py
from django.db import models
class SomeModel(models.Model):
    name = models.CharField(max_length=100)
    some_age = models.PositiveSmallIntegerField()


# filterset.py

from django_filters import rest_framework as filters
from django_filters import fields, widgets

class CustomRangeWidget(widgets.RangeWidget):
    """override RangeWidget to use custom separator"""
    def suffixed(self, name, suffix):
        separator = "__"  # my custom separator override
        return separator.join([name, suffix]) if suffix else name


class CustomRangeField(fields.RangeField):
    """Override RangeField to use custom widget"""
    widget = CustomRangeWidget

class CustomNumericRangeFilter(filters.RangeFilter):
    """Override RangeFilter to use custom field_class"""
    field_class = CustomRangeField    


class PublicationFilterSet(filters.FilterSet):
    some_age = CustomNumericRangeFilter
  1. Connect such filterset to your model view
  2. Check the generated schema

Expected behavior
I expect that shema should be a bit more dynamicly generated and use existing functionality for building field_names on RangeFilters.
Here is my suggestion how to do it

field_names = [
    filter_field.field_class.widget().suffixed(field_name, suffix) for suffix in suffixes
]

instead

field_names = [
    f'{field_name}_{suffix}' if suffix else field_name for suffix in suffixes
]
@DoubleTroubleOf
Copy link
Author

Suggested changes in #1352

@DoubleTroubleOf DoubleTroubleOf changed the title API Schema generating wrong is SuffixedMultiWidget overriden API Schema generating wrong if SuffixedMultiWidget overriden Dec 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant