Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [UNRELEASED]
### Added
- add support for python 3.14
- Add support for python 3.14

### Changed (backward-incompatible)
- set minimum version of drf-spectacular to 0.29.0
- Set the minimum version of drf-spectacular to 0.29.0
- Account for the `format` query parameter raising 404 errors when generating the API schema for error responses. This
will result in any project using the default value for `REST_FRAMEWORK["URL_FORMAT_OVERRIDE"]"` showing 404 errors for
every operation. That's because DRF enables the `format` query parameter in every endpoint by default. If you don't
need the `format` query parameter for content negotiation, you can disable it with by setting `"URL_FORMAT_OVERRIDE"`
to `None` in DRF settings. Refer
to [DRF docs](https://www.django-rest-framework.org/api-guide/settings/#url_format_override) for more information.

## [0.15.0] - 2025-06-09
### Added
Expand Down
11 changes: 11 additions & 0 deletions docs/openapi.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,17 @@ class CustomSerializer(serializers.Serializer):

## Tips and Tricks

### Hide 404 error responses due to the `format` query parameter

Set `REST_FRAMEWORK["URL_FORMAT_OVERRIDE"]"` to `None` if you're not relying on a query parameter for content
negotiation. This avoids showing a 404 error response in the API schema for every operation.

By default, DRF sets the value for `REST_FRAMEWORK["URL_FORMAT_OVERRIDE"]"` to `format`. That allows API consumers to
send a `format` query parameter in every operation for content negotiation. If the API cannot handle the requested
`format`, it will return a 404 error response. From the perspective of this package, that means every operation can
return a 404 response when using the default content negotiator. Refer
to [DRF docs](https://www.django-rest-framework.org/api-guide/settings/#url_format_override) for more information.

### Hide error responses that show in every operation

By default, the error response for all supported status codes will be added to the schema. Some of these status
Expand Down
8 changes: 8 additions & 0 deletions drf_standardized_errors/openapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from rest_framework.pagination import CursorPagination, PageNumberPagination
from rest_framework.parsers import FileUploadParser, JSONParser, MultiPartParser
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.settings import api_settings as drf_settings
from rest_framework.versioning import (
AcceptHeaderVersioning,
HostNameVersioning,
Expand Down Expand Up @@ -203,10 +204,17 @@ def _should_add_http404_error_response(self) -> bool:
if parameter["in"] == "path"
]
)
# the default content negotiator can raise a 404 when no renderer can handle
# to the format parameter in the URL
content_negotiator = self.view.get_content_negotiator()
view_can_have_no_renderers = (
self.view.format_kwarg or drf_settings.URL_FORMAT_OVERRIDE
) and isinstance(content_negotiator, DefaultContentNegotiation)
return (
paginator_can_raise_404
or versioning_scheme_can_raise_404
or has_path_parameters
or view_can_have_no_renderers
)

def _should_add_http405_error_response(self) -> bool:
Expand Down
1 change: 1 addition & 0 deletions tests/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"DEFAULT_AUTHENTICATION_CLASSES": [],
"DEFAULT_PERMISSION_CLASSES": [],
"TEST_REQUEST_DEFAULT_FORMAT": "json",
"URL_FORMAT_OVERRIDE": None,
"DEFAULT_SCHEMA_CLASS": "drf_standardized_errors.openapi.AutoSchema",
}

Expand Down
13 changes: 13 additions & 0 deletions tests/test_openapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,19 @@ def test_404_error_when_url_parameters():
assert "404" in responses


def test_404_error_when_url_format_enabled(settings):
settings.REST_FRAMEWORK = {
**settings.REST_FRAMEWORK,
"URL_FORMAT_OVERRIDE": "format",
}

route = "not-found/"
view = DummyView.as_view()
schema = generate_view_schema(route, view)
responses = get_responses(schema, route)
assert "404" in responses


def test_no_404_error():
route = "not-found/"
view = DummyView.as_view()
Expand Down
Loading