Bummer! This is just a preview. You need to be signed in with a Basic account to view the entire video.
How can viewsets and routers help you with Django REST Framework?
If you looked at the documentation for ad hoc viewset methods, you might be confused by the use of
@detail_route. REST framework offers two decorators for ad hoc methods,
@list_route might seem to make more sense because you are, in fact, returning a list. The main difference between the two decorators, however, is that
@detail_route is designed to receive a primary key argument. You need the primary key of the current course to be able to filter the reviews, so you'd use
@detail_route instead of
Speaking of documentation:
I've already shown you how to override generic view methods so 0:00 that you can be more explicit about the data that you want. 0:03 While doing that, I also made sure that when a user creates a review 0:05 it gets linked to the correct course even if they try to be sneaky. 0:08 Now, though, I'm going to pretend it's a year later and 0:12 I've been asked to build version two of the API. 0:14 This time, though, I want to use some cool new features that I've learned about 0:17 called view sets and routers that should simplify my work even more 0:19 the current yourself for courses is slash API slash B one slash courses. 0:24 To see the reviews for a course you dip in the courses PK and 0:28 slash reviews to that URL. 0:32 I want to keep the structure but everything will be easier if I move 0:34 the review URLs to slash API slash B2 slash reviews. 0:37 The detail update and destroy views for reviews will add the review primary key to 0:41 the end of the URL like so, /api/v2/reviews/1/. 0:46 So you caught the v2 in the URL right. 0:51 These changes will likely break the existing API for users. 0:54 I really like my current users and don't really want to upset them the best plan 0:57 then is to create a new version of the API current users can still use V one and 1:02 they can upgrade to V two when they're ready. 1:06 The great thing is I can run both versions of the API in the same codebase. 1:08 So, what about those two things I mentioned view sets and routers? 1:13 Routers arrest frameworks way of automating URL creation for API views. 1:17 It's not a big burden, but wouldn't it be nice to not have to write out each URL. 1:21 Routers are designed to work seamlessly with view sets. 1:25 View sets allow you to combine all of the logic for 1:29 a set of related views into a single class called a view set. 1:31 So instead of creating a list create API view and retrieve update destroy view for 1:35 every resource, you can do this all in one class and 1:39 at the cherry on top let the router generate the URLs for you. 1:42 Now, let me jump into work spaces and show you these great tools. 1:46 Okay, so I'm back here in courses views.pi and 1:50 as usual I have something I need to import. 1:54 So from rest_framework import viewsets, okay. 1:58 And I'm going to do all of my work down here 2:05 because I want to leave these existing views for 2:09 the V one version of the API right I don't want to change any of these. 2:12 I gotta keep both of these API is running, so 2:16 let me do my work down here, so I'm going to create a course View set. 2:20 And it's gonna come from viewSets.model, not models, ModelViewSet and 2:26 much like the generic view, it gets a query set argument. 2:33 So models.course.objects.all because I 2:39 need all of them objects and also like the previous views, 2:44 it gets a Serializer class which is going to be 2:50 models are not models serializer.courseSerializer. 2:55 All right, and while I'm at it I might as well make the next on so 3:02 reviews, view, set, try saying that a couple 3:08 of times fast view sets dot model view set and 3:13 again querysetmodels.review.objects.all and 3:18 serializerclass=serializers.reviewseriali- zer. 3:23 All right, believe it or not again that's it. 3:29 So now I need to go make a router to generate the URLs. 3:34 And I'm not going to do that in courses URLs. 3:37 I'm actually going to do that in the global, site wide projects URLs. 3:41 And the reason I'll do that is because it's just simpler to do it there. 3:47 So I need to import routers from a rest framework. 3:52 So from rest_framework. 3:56 Import routers and I also need to import 4:00 the views from courses so from courses import views. 4:05 All right, so now I need to create the router and 4:10 register the view sets that I created to it. 4:13 So up here below the imports but above urlpatterns, 4:17 I'm going to do router=routers.SimpleRouter 4:23 and then I'm going to register a couple of things with this. 4:29 It's kind of like registering with the admin so router register courses 4:31 views.courseview set and 4:38 router.register at 4:44 reviews Views.ReviewViewSet. 4:48 Okay, so what does this do? 4:54 Well, so first I've created an instance of simple router, 4:55 which is as you might have guessed, a simple router. 4:59 The next thing that I've done is I've registered my 5:04 view sets with the router and I've given them a prefix. 5:09 So basically, I want all of the views, in this view set, to start at courses. 5:14 All right, put all these things right here. 5:20 And I did the same thing with reviews. 5:22 So the last thing that I have to do is, I have to include my views. 5:25 So I'm gonna do URL carrot Apiv2, and 5:31 then I'm going to include router.urls and 5:35 the namespace is going to be apiv2 just so 5:40 that I've got that like in mind. 5:45 So, all of these are going to be at API v two, and 5:51 since I put like courses here, they'll show up in the same place. 5:55 Reviews, reviews. 5:59 Yeah cool. 6:01 All right and any future reviews as they get registered will automatically be 6:02 included as soon as I register them with the router which is pretty neat. 6:06 You could put the router into it's own file if you would have like a router stop 6:11 by inside courses and then from courses import the router. 6:15 But if you end up with more than one view size for more than one routers in your 6:18 project like maybe you have multiple apps that all contribute to your API. 6:23 That becomes a little bit more difficult to handle the registration and 6:29 combining of all this stuff. 6:32 So it's just easier, at least to me, to put it all and 6:34 here, but I'll leave it up to you can decide what ever you would like to do. 6:37 Okay, so, again, I have to go in the here and run my server. 6:42 I don't know why that's acting up. 6:46 But let's go see if these URLs work. 6:48 So I'm gonna go to let's just go to V2 courses, there we go. 6:51 V2 courses and cool, I mean this looks pretty familiar. 6:57 All right so let me try looking at a detail view so 7:03 I should really go to /2 and there's Python collections. 7:07 All right, so that's cool. 7:13 I know that number one has some reviews. 7:15 So let me try going back to that because that worked before, right? 7:19 Probably isn't going to work though. 7:23 Yeah, because we didn't do anything about that. 7:25 I didn't specify anything there. 7:27 So I got a 404, I should probably fix this. 7:29 Rest frameworks view sets only generate typical crud views from one model. 7:33 So you get create retrieve update and delete for one single model, 7:38 like the course model or the review model they do include a way to create ad 7:42 hoc methods onto a view set and I can use that for exactly this kind of use case. 7:48 So I'm going to import a decorator create a method stuff like that so. 7:54 Let's go back up here from rust framework 8:01 framework .decorators import detail_route and 8:06 from rest_framework.response import response. 8:12 Hey, there's that one again. 8:19 All right, so now I'm gonna come down here to 8:20 my CourseViewSet which probably is around line 47. 8:24 And this is going to the one where I'm going to create the new method. 8:28 So, first thing is I know that I'm going to decorate this with 8:32 the detail route decorator. 8:36 So, detail route and I want specify what the methods are, 8:37 I don't want this to be used to create new reviews. 8:42 That's just too much trouble. 8:46 So I'm just going to use this to get the reviews. 8:48 And we're gonna call this reviews, which I'll make it slash reviews and 8:53 self requests and the PK by default equals nine. 8:59 So course is going to be self-taught yet object. 9:05 And it will use that PK that comes in to get the object from the quarry set. 9:10 So, we've made the list view kind of act like, or 9:15 not list view, we've specify this is being a new detail view, right. 9:18 That is going to get a single object and then serializer 9:22 equals serializer dot review serializer. 9:26 And I'm going to give this course.reviews.all. 9:31 And since there's more than one, the many equals True and 9:36 a return response of serializer.data. 9:40 All right, so cool, yeah. 9:44 If I wanted this to respond to a post, I could put post here instead or 9:49 in addition if I want to handle both of them, whatever. 9:53 I try to make these things as just simple and 9:56 straightforward as I can because when you get into these places where 9:58 you're kind of working on edge cases, they get a little weirder. 10:01 So let's try this. 10:04 Check it out. 10:07 There are my reviews for course number one so great. 10:08 A couple of things to note, the reviews are a list only. 10:15 Users can't create new reviews at the /courses/one/reviews URL. 10:19 If you're cool with not keeping the old method of getting reviews for 10:23 a course, it's probably better to just remove the special view method. 10:26 Okay, I have one final problem to solve. 10:30 Review viewset already have list, create, retrieve, update and destroy views but 10:32 I don't really want a list view here. 10:37 The reviews method I just created handles getting reviews filtered to 10:39 a specific course and the list of all existing reviews seems kind of silly. 10:42 So how do I pick and choose which methods I want in a view set? 10:47
You need to sign up for Treehouse in order to download course files.Sign up