drf-spectacular: Wrong django-filter types

django-filter fields can have a different type from the underlying model field they operate against. drf-spectacular incorrectly makes the schema type match the model field instead of the filter.

Take the following filter for example:

class UserFilter(django_filters.FilterSet):
    has_logged_in = django_filters.BooleanFilter(field_name='last_login', lookup_expr='isnull')

last_login is a datetime model field but the filter field is boolean. Currently the schema has the type for has_logged_in as datetime which is incorrect.

The reason, I believe, is this part of the code: https://github.com/tfranzel/drf-spectacular/blob/243445f719e574ef8b292428070f93d62e647ddd/drf_spectacular/contrib/django_filters.py#L57-L60

The model field type is preferred over the actual filter type.

I don’t understand why the model field is even used here. Is it to get additional information? Since the filter itself has a clear type I don’t think the mode field type is ever relevant.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 17 (10 by maintainers)

Commits related to this issue

Most upvoted comments

i’ll close the issue again as it was a simple fix and i’m pretty sure your case is now covered @elonzh

turns out django_filters.rest_framework.filters.BooleanFilter != django_filters.filters.BooleanFilter. this is the only field where there is a subclassing happening in django_filters.filters

@elonzh. easy fix for you would be to use the other import path. i’ll evaluate if and how we should fix this.

I don’t fully understand all the intricacies of this but I saw that map_filter_fields doesn’t implement all types. Maybe the logic can be inverted so map_filter_fields is used for the types it supports and we only fall back to the model otherwise?