Skip to content

Commit 17d4420

Browse files
beneschsigvef
authored andcommitted
Propagate nullability in ModelSerializer (encode#8116)
Propagate the nullability of underlying model fields in ModelSerializer when those fields are marked as read only. This ensures the correct generation of OpenAPI schemas. Fix encode#8041.
1 parent 821b69b commit 17d4420

File tree

2 files changed

+21
-3
lines changed

2 files changed

+21
-3
lines changed

rest_framework/serializers.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,9 +1326,8 @@ def include_extra_kwargs(self, kwargs, extra_kwargs):
13261326
"""
13271327
if extra_kwargs.get('read_only', False):
13281328
for attr in [
1329-
'required', 'default', 'allow_blank', 'allow_null',
1330-
'min_length', 'max_length', 'min_value', 'max_value',
1331-
'validators', 'queryset'
1329+
'required', 'default', 'allow_blank', 'min_length',
1330+
'max_length', 'min_value', 'max_value', 'validators', 'queryset'
13321331
]:
13331332
kwargs.pop(attr, None)
13341333

tests/schemas/test_openapi.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import warnings
33

44
import pytest
5+
from django.db import models
56
from django.test import RequestFactory, TestCase, override_settings
67
from django.urls import path
78
from django.utils.translation import gettext_lazy as _
@@ -110,6 +111,24 @@ class Serializer(serializers.Serializer):
110111
assert data['properties']['default_false']['default'] is False, "default must be false"
111112
assert 'default' not in data['properties']['without_default'], "default must not be defined"
112113

114+
def test_nullable_fields(self):
115+
class Model(models.Model):
116+
rw_field = models.CharField(null=True)
117+
ro_field = models.CharField(null=True)
118+
119+
class Serializer(serializers.ModelSerializer):
120+
class Meta:
121+
model = Model
122+
fields = ["rw_field", "ro_field"]
123+
read_only_fields = ["ro_field"]
124+
125+
inspector = AutoSchema()
126+
127+
data = inspector.map_serializer(Serializer())
128+
assert data['properties']['rw_field']['nullable'], "rw_field nullable must be true"
129+
assert data['properties']['ro_field']['nullable'], "ro_field nullable must be true"
130+
assert data['properties']['ro_field']['readOnly'], "ro_field read_only must be true"
131+
113132

114133
@pytest.mark.skipif(uritemplate is None, reason='uritemplate not installed.')
115134
class TestOperationIntrospection(TestCase):

0 commit comments

Comments
 (0)