Skip to content

Commit

Permalink
add support for djangorestframework-recursive #586
Browse files Browse the repository at this point in the history
  • Loading branch information
tfranzel committed Oct 23, 2021
1 parent 59f9749 commit 146982c
Show file tree
Hide file tree
Showing 7 changed files with 218 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ Features
- `djangorestframework-camel-case <https://github.com/vbabiy/djangorestframework-camel-case>`_ (via postprocessing hook ``camelize_serializer_fields``)
- `django-filter <https://github.com/carltongibson/django-filter>`_
- `drf-nested-routers <https://github.com/alanjds/drf-nested-routers>`_
- `djangorestframework-recursive <https://github.com/heywbj/django-rest-framework-recursive>`_


For more information visit the `documentation <https://drf-spectacular.readthedocs.io>`_.
Expand Down
1 change: 1 addition & 0 deletions drf_spectacular/contrib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
'rest_framework_jwt',
'rest_framework_simplejwt',
'django_filters',
'rest_framework_recursive',
]
9 changes: 9 additions & 0 deletions drf_spectacular/contrib/rest_framework_recursive.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from drf_spectacular.extensions import OpenApiSerializerFieldExtension


class RecursiveFieldExtension(OpenApiSerializerFieldExtension):
target_class = "rest_framework_recursive.fields.RecursiveField"

def map_serializer_field(self, auto_schema, direction):
component = auto_schema.resolve_serializer(self.target.proxied, direction)
return component.ref
1 change: 1 addition & 0 deletions requirements/optionals.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ djangorestframework-camel-case>=1.1.2
django-filter>=2.3.0
psycopg2-binary>=2.7.3.2
drf-nested-routers>=0.93.3
djangorestframework-recursive>=0.1.2
drf_spectacular_sidecar
60 changes: 60 additions & 0 deletions tests/contrib/test_rest_framework_recursive.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import pytest
from django.urls import path
from rest_framework import serializers
from rest_framework.decorators import api_view

from drf_spectacular.utils import extend_schema
from tests import assert_schema, generate_schema

try:
from rest_framework_recursive.fields import RecursiveField
except ImportError:
from rest_framework.fields import Field as RecursiveField


class TreeSerializer(serializers.Serializer):
name = serializers.CharField()
children = serializers.ListField(child=RecursiveField())


class PingSerializer(serializers.Serializer):
ping_id = serializers.IntegerField()
pong = RecursiveField('PongSerializer', required=False)


class PongSerializer(serializers.Serializer):
pong_id = serializers.IntegerField()
ping = PingSerializer()


class LinkSerializer(serializers.Serializer):
name = serializers.CharField(max_length=25)
next = RecursiveField(allow_null=True)


@pytest.mark.contrib('rest_framework_recursive')
def test_rest_framework_recursive(no_warnings):
@extend_schema(request=TreeSerializer, responses=TreeSerializer)
@api_view(['POST'])
def tree(request):
pass # pragma: no cover

@extend_schema(request=PingSerializer, responses=PingSerializer)
@api_view(['POST'])
def pong(request):
pass # pragma: no cover

@extend_schema(request=LinkSerializer, responses=LinkSerializer)
@api_view(['POST'])
def link(request):
pass # pragma: no cover

urlpatterns = [
path('tree', tree),
path('pong', pong),
path('link', link)
]
assert_schema(
generate_schema(None, patterns=urlpatterns),
'tests/contrib/test_rest_framework_recursive.yml'
)
143 changes: 143 additions & 0 deletions tests/contrib/test_rest_framework_recursive.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
openapi: 3.0.3
info:
title: ''
version: 0.0.0
paths:
/link:
post:
operationId: link_create
tags:
- link
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Link'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/Link'
multipart/form-data:
schema:
$ref: '#/components/schemas/Link'
required: true
security:
- cookieAuth: []
- basicAuth: []
- {}
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Link'
description: ''
/pong:
post:
operationId: pong_create
tags:
- pong
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Ping'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/Ping'
multipart/form-data:
schema:
$ref: '#/components/schemas/Ping'
required: true
security:
- cookieAuth: []
- basicAuth: []
- {}
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Ping'
description: ''
/tree:
post:
operationId: tree_create
tags:
- tree
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Tree'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/Tree'
multipart/form-data:
schema:
$ref: '#/components/schemas/Tree'
required: true
security:
- cookieAuth: []
- basicAuth: []
- {}
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Tree'
description: ''
components:
schemas:
Link:
type: object
properties:
name:
type: string
maxLength: 25
next:
allOf:
- $ref: '#/components/schemas/Link'
nullable: true
required:
- name
- next
Ping:
type: object
properties:
ping_id:
type: integer
pong:
$ref: '#/components/schemas/Pong'
required:
- ping_id
Pong:
type: object
properties:
pong_id:
type: integer
ping:
$ref: '#/components/schemas/Ping'
required:
- ping
- pong_id
Tree:
type: object
properties:
name:
type: string
children:
type: array
items:
$ref: '#/components/schemas/Tree'
required:
- children
- name
securitySchemes:
basicAuth:
type: http
scheme: basic
cookieAuth:
type: apiKey
in: cookie
name: sessionid
3 changes: 3 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,6 @@ ignore_missing_imports = True

[mypy-rest_framework_nested.*]
ignore_missing_imports = True

[mypy-rest_framework_recursive.*]
ignore_missing_imports = True

0 comments on commit 146982c

Please sign in to comment.