carltongibson/django-filter

Better Openapi documentation for null_label/null_value with ChoiceFilter needed

CelestialGuru opened this issue · 1 comments

As an example, say there is a Product model with a category nullable ForeignKey to a Category model. A filterset which allows for filtering by category ids as well as null ones can be done with the following:

class ProductFilter(django_filters.FilterSet):
    category = django_filters.ModelChoiceFilter(
        null_value="null",
        queryset=Category.objects.all(),
    )

we can /api/products/?category=1 to get products with category_id=1 and we can /api/products/?category=null to get products with category_id=None. Wonderful, if you're accessing your api with anything besides OpenApi auto-created-ui stuff like swagger or redoc.

However the openapi documentation generated for this won't let you put in anything besides integers (or whatever type the foreign key is). I'll admit I don't know exactly what I would expect to be there, but it's certainly not letting me use null.

Swagger-ui

image

Redoc

image

Schema

schema.yaml
openapi: 3.0.3
info:
title: ''
version: 0.0.0
paths:
/api/inventory/products/:
  get:
    operationId: inventory_products_list
    parameters:
    - in: query
      name: category
      schema:
        type: integer
    - name: page
      required: false
      in: query
      description: A page number within the paginated result set.
      schema:
        type: integer
    - name: page_size
      required: false
      in: query
      description: Number of results to return per page.
      schema:
        type: integer
    tags:
    - inventory
    security:
    - basicAuth: []
    - tokenAuth: []
    - {}
    responses:
      '200':
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PaginatedProductList'
        description: ''
components:
schemas:
  PaginatedProductList:
    type: object
    properties:
      count:
        type: integer
        example: 123
      next:
        type: string
        nullable: true
        format: uri
        example: http://api.example.org/accounts/?page=4
      previous:
        type: string
        nullable: true
        format: uri
        example: http://api.example.org/accounts/?page=2
      results:
        type: array
        items:
          $ref: '#/components/schemas/Product'
  Product:
    type: object
    properties:
      id:
        type: integer
        readOnly: true
      part_number:
        type: string
        maxLength: 256
      description:
        type: string
      specification:
        type: string
      category:
        type: integer
        nullable: true
      price:
        type: number
        format: double
        readOnly: true
    required:
    - id
    - part_number
    - description
    - specification
    - price
securitySchemes:
  basicAuth:
    type: http
    scheme: basic
  tokenAuth:
    type: apiKey
    in: header
    name: Authorization
    description: Token-based authentication with required prefix "Token"

The in-built schema support is deprecated and will be removed. You should migrate to using drf-spectacular, which has much richer support.