Create, Read, Update, and Delete are the operations you need on all data. As REST is a way of reading and manipulating data on a server, it has HTTP operations for each of these actions. In this lesson, you’ll walk through the complete life cycle of a database object through the Ninja REST API.
In the previous lesson, I showed you how Ninja serializes data using the
ModelSchema classes. In this lesson, I’m going put it all together and show you a complete data object life cycle.
00:29 In REST, that translates to HTTP operations: POST for Create, GET for Read, PUT or PATCH for Update, and DELETE for, well, deleting. One out of four ain’t bad. Ninja provides a decorator for each one of these operations.
There’s another attribute you can use instead. That’s
model_exclude. In this case, all the fields will be used except for the ID. Of course, that’s just the description field in this case, but you get the idea. For a larger class, this can save you some typing.
02:26 This says to use all of the fields. The documentation warns against using this. You want to be careful with it. If you’re explicit about your field listing and the ORM class changes, you won’t accidentally expose anything.
With the serializers in place, let’s look at the four CRUD operations. The first is CREATE, using a
.post(). In the decorator, in addition to specifying the path, I’m also specifying the response.
03:18 This registers the call for reverse lookup. This can be a bit finicky, but I’ll come back to that in a second. The view takes its standard request, and because it’s a POST, you need to indicate what is in the request’s body.
You’ve seen this before. The
.get() decorator takes the path, declares that it will respond with a list of
GiftOut serializers, and I’ve added the
url_name here as well. Because the response is set to a list of
GiftOut serializers, all you need to do is return the
.all() call of the
WeddingGift ORM. Let me just scroll down a bit.
That’s bad practice. By using the
.get_object_or_404() shortcut, Ninja will handle both the retrieving of the object and the proper re-raising of the exception if no such object exists. In a later lesson, I’ll show you how to customize Ninja’s exception management. On to the U in CRUD.
.put() decorator is used to update an existing object. This means the path needs an ID, similar to the previous
.get(). This also responds with a
GiftOut serializer. Note the lack of a
The path here is identical to the
.get() path. It is the operation that is different. If you named this one, only one lookup would be kept because Django does the lookup based on the path. So, if called this one
update_gift, it would override the
.get(), and you’d end up with
update_gift as the name for both. It’s best to just name the first usage something generic and not name the others.
Remember, reverse lookup is based on the path, not on the operation. The view declaration includes both the
gift_id and a payload, sort of a mix between a GET and a POST. Here, you’re updating a specific object, so you need the ID of the object in order to fetch it and the fields that you’re going to change. Like with the GET, I look the object up using
Then, to replace the fields, I look through all of the fields sent in and call
.set_attr on each of them. This replaces their current contents with whatever was sent in in the payload. With the fields written to, the object needs to be saved and then just returned. Finally, the DELETE operation is used for the D in CRUD.
This time, you need a path with an ID, but you don’t declare a response in the decorator. Like the GET, you use the shortcut to fetch the object from the database, then call the ORM’s
07:15 Sometimes you’ll find APIs returning the object that was deleted. This feels fishy to me, as you’re responding with the thing you just removed. I usually just respond with some sort of success indicator.
In this case, I’m setting the
json because that’s what I’m sending. The Ninja
POST decorator expects a single data item in the request body, and that’s supposed to contain a JSON dictionary with fields.
10:26 And you’re left with just the knife. I-I-I-I want the knife. Now there’s a deep-cut reference that probably only my wife will get. I will give kudos to anybody who in the comments correctly identifies what I’m talking about.
By default, the
NinjaAPI object creates a namespace called
api-1.0.0. You can change this if you like. I’ll show you how later. Our first CRUD operation was named
create_gift, so to get it, you reverse with the namespace and the name, giving this resulting path:
There should either be a flag for
reverse or a different method for doing lookups without the arguments. Frequently, when doing single-page applications, you want pass in the URLs and then append the IDs afterwards as the user does something in the interface.
13:23 When I clicked Try it out, it gave me an editable field pre-populated with a request body. I edit the string, then click Execute. And the third gift was created. Very handy tool, this, especially when you’re debugging your views.
Become a Member to join the conversation.