updated field default on serializer according to openapi generation and added that to options action response

This commit is contained in:
Rizwan Shaikh 2023-06-27 22:55:52 +05:30
parent 34d2ad4faa
commit 728fdbe13c
3 changed files with 135 additions and 1 deletions

View File

@ -11,6 +11,7 @@ from django.http import Http404
from django.utils.encoding import force_str from django.utils.encoding import force_str
from rest_framework import exceptions, serializers from rest_framework import exceptions, serializers
from rest_framework.fields import empty
from rest_framework.request import clone_request from rest_framework.request import clone_request
from rest_framework.utils.field_mapping import ClassLookupDict from rest_framework.utils.field_mapping import ClassLookupDict
@ -149,4 +150,7 @@ class SimpleMetadata(BaseMetadata):
for choice_value, choice_name in field.choices.items() for choice_value, choice_name in field.choices.items()
] ]
if getattr(field, 'default', None) and field.default != empty and not callable(field.default):
field_info['default'] = field.default
return field_info return field_info

View File

@ -9,6 +9,7 @@ from django.db import models
from django.utils.text import capfirst from django.utils.text import capfirst
from rest_framework.compat import postgres_fields from rest_framework.compat import postgres_fields
from rest_framework.fields import empty
from rest_framework.validators import UniqueValidator from rest_framework.validators import UniqueValidator
NUMERIC_FIELD_TYPES = ( NUMERIC_FIELD_TYPES = (
@ -127,7 +128,7 @@ def get_field_kwargs(field_name, model_field):
kwargs['read_only'] = True kwargs['read_only'] = True
return kwargs return kwargs
if model_field.has_default(): if model_field.default is not None and model_field.default != empty and not callable(model_field.default):
kwargs['default'] = model_field.default kwargs['default'] = model_field.default
if model_field.has_default() or model_field.blank or model_field.null: if model_field.has_default() or model_field.blank or model_field.null:

View File

@ -184,6 +184,135 @@ class TestMetadata:
assert response.status_code == status.HTTP_200_OK assert response.status_code == status.HTTP_200_OK
assert response.data == expected assert response.data == expected
def test_actions_with_default(self):
"""
On generic views OPTIONS should return an 'actions' key with metadata
on the fields with default that may be supplied to PUT and POST requests.
"""
class NestedField(serializers.Serializer):
a = serializers.IntegerField(default=2)
b = serializers.IntegerField()
class ExampleSerializer(serializers.Serializer):
choice_field = serializers.ChoiceField(['red', 'green', 'blue'], default='red')
integer_field = serializers.IntegerField(
min_value=1, max_value=1000, default=1
)
char_field = serializers.CharField(
min_length=3, max_length=40, default="example"
)
list_field = serializers.ListField(
child=serializers.ListField(
child=serializers.IntegerField(default=1)
)
)
nested_field = NestedField()
uuid_field = serializers.UUIDField(label="UUID field")
class ExampleView(views.APIView):
"""Example view."""
def post(self, request):
pass
def get_serializer(self):
return ExampleSerializer()
view = ExampleView.as_view()
response = view(request=request)
expected = {
'name': 'Example',
'description': 'Example view.',
'renders': [
'application/json',
'text/html'
],
'parses': [
'application/json',
'application/x-www-form-urlencoded',
'multipart/form-data'
],
'actions': {
'POST': {
'choice_field': {
'type': 'choice',
'required': False,
'read_only': False,
'label': 'Choice field',
"choices": [
{'value': 'red', 'display_name': 'red'},
{'value': 'green', 'display_name': 'green'},
{'value': 'blue', 'display_name': 'blue'}
],
'default': 'red'
},
'integer_field': {
'type': 'integer',
'required': False,
'read_only': False,
'label': 'Integer field',
'min_value': 1,
'max_value': 1000,
'default': 1
},
'char_field': {
'type': 'string',
'required': False,
'read_only': False,
'label': 'Char field',
'min_length': 3,
'max_length': 40,
'default': 'example'
},
'list_field': {
'type': 'list',
'required': True,
'read_only': False,
'label': 'List field',
'child': {
'type': 'list',
'required': True,
'read_only': False,
'child': {
'type': 'integer',
'required': False,
'read_only': False,
'default': 1
}
}
},
'nested_field': {
'type': 'nested object',
'required': True,
'read_only': False,
'label': 'Nested field',
'children': {
'a': {
'type': 'integer',
'required': False,
'read_only': False,
'label': 'A',
'default': 2
},
'b': {
'type': 'integer',
'required': True,
'read_only': False,
'label': 'B'
}
}
},
'uuid_field': {
'type': 'string',
'required': True,
'read_only': False,
'label': 'UUID field'
}
}
}
}
assert response.status_code == status.HTTP_200_OK
assert response.data == expected
def test_global_permissions(self): def test_global_permissions(self):
""" """
If a user does not have global permissions on an action, then any If a user does not have global permissions on an action, then any