Skip to content

[django-filter] Exception raised while trying resolve model field for django-filter field #690

@TheSuperiorStanislav

Description

@TheSuperiorStanislav

Describe the bug
drf-spectacular==0.22.0 fails to recognize the type of filter if its name doesn't match with one of the fields of model. Works fine with drf-spectacular==0.21.*.

To Reproduce

class EventFilter(filters.FilterSet):
    """Filter class for `Event` model."""

    availability_status = filters.ChoiceFilter(
        label="Availability Status",
        method="filter_by_availability_status",
        choices=models.Event.AvailabilityStatus.choices,
    )

    class Meta:
        model = models.Event
        fields = dict(
            date=["gte", "lte"],
        )

    def filter_by_availability_status(self, queryset, name, value):
        """Filter event by availability_status."""
        if value:
            return queryset.filter(_availability_status=value)
        return queryset

Which produces the following message while running spectacular command

python manage.py spectacular --file .tmp/schema.yaml --validate --fail-on-warn
Warning #0: EventViewSet: EventFilter: Exception raised while trying resolve model field for django-filter field "availability_status". Defaulting to string (Exception: 'availability_status')

Expected behavior
No warnings and python manage.py spectacular --file .tmp/schema.yaml --validate --fail-on-warn command is not failing

Quick fix
You can fix by setting field type manually via extend_schema_field

class EventFilter(filters.FilterSet):
    """Filter class for `Event` model."""

    availability_status = filters.ChoiceFilter(
        label="Availability Status",
        method="filter_by_availability_status",
        choices=models.Event.AvailabilityStatus.choices,
    )

    class Meta:
        model = models.Event
        fields = dict(
            date=["gte", "lte"],
        )

	@extend_schema_field(OpenApiTypes.STR) # <- Manually set field type
    def filter_by_availability_status(self, queryset, name, value):
        """Filter event by availability_status."""
        if value:
            return queryset.filter(_availability_status=value)
        return queryset

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestfix confirmation pendingissue has been fixed and confirmation from issue reporter is pending

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions