Skip to content

Commit 55b38f1

Browse files
committed
Check for reserved field names in serializer meta class
Fixes django-json-api#518 Fixes django-json-api#720 This is to avoid an incomprehensible exception during runtime when either meta or results is used as a field name.
1 parent 29971b4 commit 55b38f1

File tree

3 files changed

+36
-1
lines changed

3 files changed

+36
-1
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ any parts of the framework not mentioned in the documentation should generally b
1212

1313
### Fixed
1414

15-
* Adjusted error messages to correctly use capitial "JSON:API" abbreviation as used in the specification.
15+
* Adjusted error messages to correctly use capital "JSON:API" abbreviation as used in the specification.
1616
* Avoid error when `parser_context` is `None` while parsing.
17+
* Raise comprehensible error when reserved field names `meta` and `results` are used.
1718

1819
### Changed
1920

rest_framework_json_api/serializers.py

+19
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,25 @@ def __repr__(self):
184184

185185

186186
class SerializerMetaclass(SerializerMetaclass):
187+
188+
_reserved_field_names = {"meta", "results"}
189+
190+
@classmethod
191+
def _get_declared_fields(cls, bases, attrs):
192+
fields = super()._get_declared_fields(bases, attrs)
193+
194+
found_reserved_field_names = cls._reserved_field_names.intersection(
195+
fields.keys()
196+
)
197+
if found_reserved_field_names:
198+
raise AttributeError(
199+
f"Serializer class {attrs['__module__']}.{attrs['__qualname__']} uses "
200+
f"following reserved field name(s) which is not allowed: "
201+
f"{', '.join(sorted(found_reserved_field_names))}"
202+
)
203+
204+
return fields
205+
187206
def __new__(cls, name, bases, attrs):
188207
serializer = super().__new__(cls, name, bases, attrs)
189208

tests/test_serializers.py

+15
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import pytest
12
from django.db import models
23

34
from rest_framework_json_api import serializers
@@ -33,3 +34,17 @@ class Meta:
3334
}
3435

3536
assert included_serializers == expected_included_serializers
37+
38+
39+
def test_reserved_field_names():
40+
with pytest.raises(AttributeError) as e:
41+
42+
class ReservedFieldNamesSerializer(serializers.Serializer):
43+
meta = serializers.CharField()
44+
results = serializers.CharField()
45+
46+
assert str(e.value) == (
47+
"Serializer class tests.test_serializers.test_reserved_field_names.<locals>."
48+
"ReservedFieldNamesSerializer uses following reserved field name(s) which is "
49+
"not allowed: meta, results"
50+
)

0 commit comments

Comments
 (0)