Skip to content

Commit 2a56a35

Browse files
author
Maxence
committed
Manage nested serializer and list fields/serializers in Endpoint fields
1 parent e866a41 commit 2a56a35

File tree

5 files changed

+49
-14
lines changed

5 files changed

+49
-14
lines changed

Diff for: demo/project/accounts/serializers.py

+10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from rest_framework import serializers
22
from project.accounts.models import User
3+
from rest_framework.authtoken.serializers import AuthTokenSerializer
34

45

56
class UserRegistrationSerializer(serializers.ModelSerializer):
@@ -30,3 +31,12 @@ class Meta:
3031
model = User
3132
fields = ('id', 'token', 'password',)
3233
extra_kwargs = {'password': {'write_only': True}}
34+
35+
36+
class NestedSerializer(serializers.Serializer):
37+
nb_test = serializers.IntegerField(default=0, required=False)
38+
liste_codes = serializers.ListField(child=serializers.CharField())
39+
40+
41+
class CustomAuthTokenSerializer(AuthTokenSerializer):
42+
nested = NestedSerializer(many=True)

Diff for: demo/project/accounts/views.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@
22
from django.views.generic.base import TemplateView
33
from rest_framework import parsers, renderers, generics, status
44
from rest_framework.authtoken.models import Token
5-
from rest_framework.authtoken.serializers import AuthTokenSerializer
65
from rest_framework.permissions import AllowAny
76
from rest_framework.response import Response
87
from rest_framework.views import APIView
98
from project.accounts.models import User
109
from project.accounts.serializers import (
11-
UserRegistrationSerializer, UserProfileSerializer, ResetPasswordSerializer
10+
UserRegistrationSerializer, UserProfileSerializer, ResetPasswordSerializer, CustomAuthTokenSerializer
1211
)
1312

1413

@@ -28,7 +27,7 @@ class LoginView(APIView):
2827
permission_classes = ()
2928
parser_classes = (parsers.FormParser, parsers.MultiPartParser, parsers.JSONParser,)
3029
renderer_classes = (renderers.JSONRenderer,)
31-
serializer_class = AuthTokenSerializer
30+
serializer_class = CustomAuthTokenSerializer
3231

3332
def post(self, request):
3433
serializer = self.serializer_class(data=request.data)

Diff for: rest_framework_docs/api_endpoint.py

+20-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import json
22
import inspect
33
from django.contrib.admindocs.views import simplify_regex
4+
from rest_framework import serializers
45
from rest_framework.viewsets import ModelViewSet
56

67

@@ -50,11 +51,7 @@ def __get_serializer_fields__(self):
5051
serializer = self.callback.cls.serializer_class
5152
if hasattr(serializer, 'get_fields'):
5253
try:
53-
fields = [{
54-
"name": key,
55-
"type": str(field.__class__.__name__),
56-
"required": field.required
57-
} for key, field in serializer().get_fields().items()]
54+
fields = self.__get_fields__(serializer)
5855
except KeyError as e:
5956
self.errors = e
6057
fields = []
@@ -64,6 +61,24 @@ def __get_serializer_fields__(self):
6461

6562
return fields
6663

64+
def __get_fields__(self, serializer):
65+
fields = []
66+
for key, field in serializer().get_fields().items():
67+
item = dict(
68+
name=key,
69+
type=str(field.__class__.__name__),
70+
required=field.required
71+
)
72+
if isinstance(field, (serializers.ListSerializer, serializers.ListField)):
73+
sub_type = field.child.__class__
74+
item['sub_type'] = str(sub_type.__name__)
75+
if isinstance(sub_type(), serializers.Serializer):
76+
item['fields'] = self.__get_fields__(sub_type)
77+
elif isinstance(field, serializers.Serializer):
78+
item['fields'] = self.__get_fields__(field)
79+
fields.append(item)
80+
return fields
81+
6782
def __get_serializer_fields_json__(self):
6883
# FIXME:
6984
# Return JSON or not?
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<ul class="list fields">
2+
{% for field in item.fields %}
3+
<li class="field">
4+
{{ field.name }}: {{ field.type }} {% if field.required %}<span class="label label-primary label-required"
5+
title="Required">R</span>{% endif %}
6+
{% if field.sub_type %} ({{ field.sub_type }}) {% endif %}
7+
{% if field.fields %}
8+
{% with field as item %}
9+
{% include 'rest_framework_docs/fields.html' %}
10+
{% endwith %}
11+
{% endif %}
12+
</li>
13+
{% endfor %}
14+
</ul>

Diff for: rest_framework_docs/templates/rest_framework_docs/home.html

+3-6
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,11 @@ <h4 class="panel-title title">
6565
{% if endpoint.errors %}
6666
<div class="alert alert-danger" role="alert">Oops! There was something wrong with {{ endpoint.errors }}. Please check your code.</div>
6767
{% endif %}
68-
6968
{% if endpoint.fields %}
7069
<p class="fields-desc">Fields:</p>
71-
<ul class="list fields">
72-
{% for field in endpoint.fields %}
73-
<li class="field">{{ field.name }}: {{ field.type }} {% if field.required %}<span class="label label-primary label-required" title="Required">R</span>{% endif %}</li>
74-
{% endfor %}
75-
</ul>
70+
{% with endpoint as item %}
71+
{% include 'rest_framework_docs/fields.html' %}
72+
{% endwith %}
7673
{% elif not endpoint.errors %}
7774
<p>No fields.</p>
7875
{% endif %}

0 commit comments

Comments
 (0)