carltongibson / django-filter

A generic system for filtering Django QuerySets based on user selections
https://django-filter.readthedocs.io/en/main/
Other
4.41k stars 766 forks source link

Better Openapi documentation for null_label/null_value with ChoiceFilter needed #1593

Closed CelestialGuru closed 1 year ago

CelestialGuru commented 1 year ago

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 ```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" ```
carltongibson commented 1 year ago

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