Skip to content

Swagger / OpenAPI

DjFilterBackend implements DRF's schema introspection hooks, so any filter you declare automatically shows up as query parameters in your generated OpenAPI / Swagger schema. Both major schema generators are supported with no extra wiring.

Supported generators

Generator Status What gets called
drf-spectacular (OpenAPI 3) get_schema_operation_parameters(view)
drf-yasg (OpenAPI 2) get_schema_operation_parameters(view) (yasg downgrades to OpenAPI 2 internally)
DRF's built-in AutoSchema (OpenAPI 3) get_schema_operation_parameters(view)
Legacy coreapi schema ✓ (deprecated) get_schema_fields(view)

You don't need to add anything to your filter classes — the schema is generated by introspecting the declared fields.

Type mapping

Each filter field is mapped to an OpenAPI type/format pair. Fields with choices get an enum; ListField and RangeField become type: array with items derived from the child field.

Filter field OpenAPI 3 schema
CharField, SlugField, IPAddressField {type: string}
EmailField {type: string, format: email}
URLField {type: string, format: uri}
IntegerField, PrimaryKeyRelatedField {type: integer}
FloatField {type: number, format: float}
DecimalField {type: number, format: double}
BooleanField {type: boolean}
DateField {type: string, format: date}
DateTimeField {type: string, format: date-time}
TimeField {type: string, format: time}
DurationField {type: string, format: duration}
ChoiceField {type: string, enum: [...]}
ListField(child=X) {type: array, items: <X-schema>}
RangeField(child=X) {type: array, items: <X-schema>, minItems: 2, maxItems: 2}

drf-spectacular setup

# settings.py
INSTALLED_APPS = [
    ...,
    "drf_spectacular",
]

REST_FRAMEWORK = {
    "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
}
# urls.py
from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView

urlpatterns = [
    ...,
    path("api/schema/", SpectacularAPIView.as_view(), name="schema"),
    path("api/docs/",   SpectacularSwaggerView.as_view(url_name="schema")),
]

Filter parameters appear under each operation's parameters array with the types from the table above.

drf-yasg setup

# settings.py
INSTALLED_APPS = [
    ...,
    "drf_yasg",
]
# urls.py
from drf_yasg import openapi
from drf_yasg.views import get_schema_view

schema_view = get_schema_view(
    openapi.Info(title="My API", default_version="v1"),
    public=True,
)

urlpatterns = [
    ...,
    path("api/docs/", schema_view.with_ui("swagger", cache_timeout=0)),
]

drf-yasg picks up the same get_schema_operation_parameters output and translates it into Swagger 2.0 parameters.

Edge cases

  • Views without a filter_class — both schema methods return [] cleanly, so a single DjFilterBackend registered globally won't break introspection on views that don't filter.
  • ChoicesChoiceField's configured choices are emitted as the enum array on the parameter schema, so Swagger UI renders a dropdown.
  • Required vs optional — by default every filter field is required=False; mark it required=True (directly or via Meta.extra_kwargs) and it shows as required in the schema.
  • help_text — used as the parameter description. Falls back to label, then to the field name.