django-ninja
django-ninja copied to clipboard
Correct usage of ForeignKey Ids in Model Schema
I want to write a CRUD style API. I retrieve the model data, and save the model data. I want to do that using the schema mapped from the Django Model.
When I try it, the schema serialises using the django model attribute name. However, the validator expects the _id suffix. I am looking for the recommended way to configure the ModelSchema below to generate a JSON version with the attribute "content_type_id", instead of "content_type".
Here is an example. Execute using "python manage.py shell"
from django.contrib.auth.models import Permission
from pprint import pp
from ninja import ModelSchema, Field
class PermissionSchema(ModelSchema):
class Meta:
model = Permission
fields = "__all__"
perm = Permission.objects.first()
serialiser = PermissionSchema.from_orm(perm)
d = serialiser.dict()
pp(d)
# {'id': 5, 'name': 'Can add group', 'content_type': 2, 'codename': 'add_group'}
PermissionSchema.model_validate(d)
# Traceback (most recent call last):
# File "<console>", line 1, in <module>
# File "/home/vscode/.local/lib/python3.11/site-packages/pydantic/main.py", line 596, in model_validate
# return cls.__pydantic_validator__.validate_python(
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# pydantic_core._pydantic_core.ValidationError: 1 validation error for PermissionSchema
# content_type_id
# Field required [type=missing, input_value=<DjangoGetter: {'id': 5, ...codename': 'add_group'}>, input_type=DjangoGetter]
# For further information visit https://errors.pydantic.dev/2.9/v/missing
If I move the field content_type to content_type_id, it can parse
d["content_type_id"] = d.pop("content_type")
PermissionSchema.model_validate(d)
# PermissionSchema(id=5, name='Can add group', content_type=2, codename='add_group')
Note - the property name in the schema is "content_type_id", but the generated output is "content_type"
pp(PermissionSchema.schema())
# {'properties': {'id': {'anyOf': [{'type': 'integer'}, {'type': 'null'}],
# 'title': 'ID'},
# 'name': {'maxLength': 255, 'title': 'Name', 'type': 'string'},
# 'content_type_id': {'title': 'Content Type', 'type': 'integer'},
# 'codename': {'maxLength': 100,
# 'title': 'Codename',
# 'type': 'string'}},
# 'required': ['name', 'content_type_id', 'codename'],
# 'title': 'PermissionSchema',
# 'type': 'object'}