Learn how to override generic view methods for data filtering and more.
Previously I converted my API view class 0:00 over to using rest frameworks generic view. 0:03 That made my code more concise and 0:05 cut out a good chunk of the work I had to do myself. 0:07 Right now I have the ability to list all of the courses retrieve a single course 0:10 and create update and destroy courses. 0:14 That's a pretty good start, but courses aren't nearly as much fun without reviews 0:16 and right now I don't have any way to get reviews. 0:20 I'm going to use more of the same generic views for reviews for 0:24 these views though I'm going to need to do a bit of extra work 0:28 to make sure of the reviews are filtered to the specific course that I'm viewing. 0:30 Let me talk you through this real quick. 0:34 The URL to view the course details is something like /api/v1/courses/1/ what 0:36 I want is to be able to access the reviews for a course by extending that URL like so 0:43 /api/v1/courses/1/reviews/ by 0:48 appending /reviews to the end of the URL users of the API should know 0:52 that they're asking for a views pertaining to the course with that primary key. 0:57 Going even deeper adding another primary key 1:01 to that URL like /api/v1/courses/1/reviews/1/ should 1:04 give just that single specific review that belongs to that single specific course. 1:09 So I'm still here in courses_view.py and 1:14 the first thing I wanna do is create my list create_view for my reviews. 1:18 So class list create review 1:25 and this is going to also be generics list create API view 1:31 and once again query set is going to be models dot not course but 1:37 review dot objects to all. 1:42 And nice serializer_class 1:44 is going to be serializers.ReviewSerializer. 1:49 I wish serializer was a little bit easier word to type. 1:54 This should be looking pretty familiar by now the only thing that really changed is 1:58 I'm using Review in the places where I was using Course before. 2:01 All right so onwards and upwards let's make the detail view. 2:06 You know what, I'm gonna get lazy here. 2:09 Actually I'm gonna get really lazy here and 2:12 paste and 2:16 review, review. 2:20 Review. Wow, so lazy. 2:30 Right, so just like it did before, right? 2:33 Just different model and serializer. 2:36 And now I'm going to create the reviews so that, well, so I don't forget to do them. 2:38 And so that when I modify my new API views you'll have a better idea of why. 2:43 So over here again and I'm going to do a review and 2:50 then mark and then we're going to do P and 2:56 we're going to do course P.K. and then reviews and 3:00 this will be of views dot list create review dot as view. 3:07 And the name Movie Review lists and again going to 3:13 put these on new lines they're just way too long. 3:17 All right. 3:21 And then the last one here will 3:23 be review the URL quote caret 3:29 P course P.K. D plus reviews P. 3:34 That thing PK. 3:40 D plus. 3:44 That, that. 3:46 Yeah. 3:47 Check out that rejects 3:48 views.retrieveupdatedestroyreview as 3:51 review name equals review detail. 3:56 All right. 4:00 These URLs are you know a little bit different right. 4:04 I'm sure that you noticed that the first keyword argument for 4:07 each of these is Course P K so obviously that's going to relate to 4:10 a courses primary key and not to a reviews primary key. 4:14 The detail view for 4:19 a review is gonna need, I mean there's gonna need the course they belong to. 4:20 So we're gonna keep that in mind that the review views 4:26 will now receive a course PK argument. 4:30 Okay. 4:33 So now let's come back over here to views.py to make sure that I am filtering 4:34 the data properly. 4:39 Now the first thing that I need to do is here on ListCreateReview, 4:41 I need to override the get_quereyset argument method. 4:45 Sorry. 4:51 So get_queryset is the Method that figures out how to get the query set. 4:52 Right? 5:00 So, this is the place where I can take and 5:01 use that course PK to figure out what I'm doing. 5:04 So I'm going to return return self.query set.filter. 5:07 Where the course_id is equal to the self.kwags.get course_pk. 5:14 All right so I already have a query set here 5:21 now further filter it to where the course_id is this one that comes in here. 5:26 And by using course ID I save myself a database look up I don't have to do 5:32 course not ID, where I actually have to go and get the courses and find that stuff. 5:36 All right. 5:41 So that's pretty cool I should actually be able to test that one right now. 5:42 So, reviews 5:46 I think I did something wrong in my serializer. 5:55 This should be comment. 5:58 There we go. 6:03 So this is now the reviews for course number one which there is one 6:05 review from somebody named Kenneth I don't know who that was and 6:10 they gave it a five which is really nice of them. 6:13 Thanks Kenneth for giving me a five on that. 6:15 Okay, so one other thing that would be handy here is because of what I'm doing 6:19 here where I'm kind of messing with this stuff is I'm making it to where 6:26 nobody can create one that goes to a different thing right. 6:33 So at least that's what I want to do right. 6:38 I want to make sure that this post data like when you were on course number one. 6:42 So if you were to change this to course number three and then submit it. 6:48 I don't want that to happen I want this. 6:52 I want it to come into course number one. 6:54 So let's do this then 6:56 the reason is that this isn't that big of a deal on these courses and 6:59 these reviews but maybe I'm using user I.D.'s to tie things to specific users. 7:02 I don't want to user to be able you know maybe it's Twitter right. 7:07 I don't want a user to be able to post a tweet as another user that would be 7:11 you know dangerous so up here I'm going to import 7:16 Django shortcuts as get object or for 7:23 four o four which that will let me handle 404s and 7:28 then another method that I'm going to override here is the perform create. 7:33 And so what perform create does is perform create is the method that's run 7:42 right when an object is being created by The View. 7:47 So I'm gonna say that course = get_object_or_404 7:50 models.Course pk = self.kwags.get course_pk. 7:57 And then serializer.save course = course. 8:05 So all this does is this prevents a user from being able to 8:13 give a different P.K. when they submit that. 8:18 So that's great, and I want to make sure that the review detail 8:21 has a similar bit of action right. 8:26 So I'm gonna come down here and override a new method here which is getObject. 8:31 getObject is very similar to get_queryset but 8:37 whereas get_queryset that gets multiple 8:43 items getObject gets a single item. 8:49 So I'll return getObject or_484 out of self.get_querreyset. 8:54 So that just goes ahead and gets the query set and then course_id equals 9:03 self.kwargs.get Course_pk and 9:08 then the actual pk is equal to self.kwargs.get pk. 9:13 So what this is doing is we're saying out of this quereyset, 9:18 get a single object that has this course_id and has this pk right. 9:21 So I'm just overwriting those two things. 9:26 I'm asking for a specific review from a specific course. 9:29 All right, so for some reason my thing down here refreshed. 9:33 So, I got to get in there to run that again which that's kind of annoying. 9:38 So, I'm going to try and be sneaky and I want to try like we're talking 9:44 about I'm going to try to send in a review for something other than this one. 9:49 So this is from Kenneth@teamtreehouse. 9:55 Great course, and I would give a rating of two because I don't know how numbers work. 10:00 I'm gonna try to post that. 10:05 What is up? 10:10 I can't 10:11 do that because I can't send in more than one review for that same course. 10:20 Which means that it did what I wanted, because I already had a review for 10:27 Course 1. 10:31 So it changed that to one instead of three. 10:33 So that's awesome. 10:35 It did exactly what I wanted prevented me from changing the course ID and 10:37 prevented me from submitting more than one review. 10:41 So great work during a rest frame work. 10:45 There are lots of useful methods you can override in rest framework generic views. 10:48 I've included a link in the teacher's notes and 10:52 I strongly suggest getting familiar with the available methods. 10:54 I'm pretty sure it'd be possible to reduce our code even further. 10:58 Come back for the next video and see how. 11:01
You need to sign up for Treehouse in order to download course files.Sign up