diff --git a/CHANGELOG.md b/CHANGELOG.md index a9dc65db..a5f86d1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ any parts of the framework not mentioned in the documentation should generally b ``` * `SerializerMethodResourceRelatedField(many=True)` relationship data now includes a meta section. +* Required relationship fields are now marked as required in the OpenAPI schema. ### Fixed diff --git a/example/tests/__snapshots__/test_openapi.ambr b/example/tests/__snapshots__/test_openapi.ambr index fd270b40..93b8f7fb 100644 --- a/example/tests/__snapshots__/test_openapi.ambr +++ b/example/tests/__snapshots__/test_openapi.ambr @@ -587,6 +587,11 @@ "$ref": "#/components/schemas/reltoone" } }, + "required": [ + "bio", + "entries", + "comments" + ], "type": "object" }, "type": { @@ -801,6 +806,11 @@ "$ref": "#/components/schemas/reltoone" } }, + "required": [ + "bio", + "entries", + "comments" + ], "type": "object" }, "type": { diff --git a/rest_framework_json_api/schemas/openapi.py b/rest_framework_json_api/schemas/openapi.py index 4a0eeb83..a0d2be0d 100644 --- a/rest_framework_json_api/schemas/openapi.py +++ b/rest_framework_json_api/schemas/openapi.py @@ -631,6 +631,15 @@ def get_request_body(self, path, method): ): # noqa E501 if "readOnly" in schema: del item_schema["properties"]["attributes"]["properties"][name] + + if "properties" in item_schema and "relationships" in item_schema["properties"]: + # No required relationships for PATCH + if ( + method in ["PATCH", "PUT"] + and "required" in item_schema["properties"]["relationships"] + ): + del item_schema["properties"]["relationships"]["required"] + return { "content": { ct: { @@ -653,6 +662,7 @@ def map_serializer(self, serializer): # TODO: remove attributes, etc. for relationshipView?? required = [] attributes = {} + relationships_required = [] relationships = {} for field in serializer.fields.values(): @@ -668,11 +678,15 @@ def map_serializer(self, serializer): ManySerializerMethodResourceRelatedField, ), ): + if field.required: + relationships_required.append(format_field_name(field.field_name)) relationships[format_field_name(field.field_name)] = { "$ref": "#/components/schemas/reltomany" } continue if isinstance(field, serializers.RelatedField): + if field.required: + relationships_required.append(format_field_name(field.field_name)) relationships[format_field_name(field.field_name)] = { "$ref": "#/components/schemas/reltoone" } @@ -727,6 +741,10 @@ def map_serializer(self, serializer): "type": "object", "properties": relationships, } + if relationships_required: + result["properties"]["relationships"][ + "required" + ] = relationships_required return result def _add_async_response(self, operation):