Schema class in Ninja defines how to group typed fields together into serializable objects. The
ModelSchema class allows for the definition of a
Schema based on an existing Django ORM object, minimizing the amount of code necessary to serialize your database objects.
Serialization Through Schema and ModelSchema Classes
00:21 This process is called serialization. Ninja is built on top of a serialization library called Pydantic. Pydantic uses the type annotation features of Python to describe objects, which it calls models.
This can be a bit confusing in the Django world, as Django already has something called a model. To get around this, Ninja renames Pydantic models as schemas. A
Schema is a Python class used to describe some fields with type information.
To play with some data, I’ll need some data. So another lesson, another Django app. This time, I’ll be playing with dragon fire. The data in question will be a
Person. The model for it is on the screen here.
It can also be found in the sample code if you want to just grab it. If you’re coding along with me, you’ll need to create a
targaryen Django app, add the
Person class in the
models file, and of course, register all this stuff … so, add it to installed apps in your settings, register an API route, and of course, because you’re adding a model, you’ll need to do migrations as well.
Inside of my
targaryen app, I’ve created
schemas.py. Ninja doesn’t care where you create this, and if you’re only doing a little bit, sticking your schemas in
models.py actually makes a little more sense. But for larger projects, you may want to organize your schemas together, like I’ve done here.
Most of the time, this will be describing the same kind of object, but usually will contain different fields. Stuff going out has an ID field, whereas stuff you’re creating, something new, typically doesn’t have an ID field. One way of handling this is to use two different serialization classes, one for
In and one for
As this is going to return a list of
DragonOut objects, the response type is set to
list[DragonOut]. Inside of the view, I can create an instance of a
DragonOut data object, or like I’ve done here, three of them.
03:54 Since Ninja is a library for Django, the most likely thing you’re going to need to serialize is Django ORM models. As an ORM model already has type information inside of it, Ninja can do most of the work for you.
ModelSchema class works a lot like a form object in Django. You inherit from the base class. Then in a subclass, you indicate what ORM model to serialize. In this case, I’m serializing the
targaryen Person model.
model_fields attribute indicates which of the fields from
Person I’m going to include in the output. In addition to using fields from
Person, you can also add new ones simply by declaring them.
I’ve declared the
full_name attribute and then created a magical little method called
.resolve_full_name(). Ninja automatically looks for static methods that start with
resolve and will use them to populate a field. A
resolve method takes an object as an argument, the thing being serialized, and then it returns the value of the field in question. Here, I’ve created
full_name by combining the name and title of the
Person object into a single string.
Now inside of the API endpoint, I declare that I’m returning a
PersonOut as a response, then return a
Person object. Ninja takes the
Person ORM object, uses the
PersonOut ModelSchema and serializes it all into JSON. Note that what I’ve done here isn’t the best coding practice.
Become a Member to join the conversation.