Editing Questions11:54 with Kenneth Love
Now that we have a handle on multiple form classes, how do we use that edit specific instances?
So like before I wanna create the edit_question view from the URL first. 0:00 So, our create question is already pretty close, but 0:06 our edit_quiz is even closer, so let's just copy that one. 0:10 And paste it right there. 0:14 And what we want it to be is we want this to be the quiz pk and 0:19 then instead of edit quiz we're going to say edit question and 0:24 then here instead of quiz pk we are going to say question pk. 0:29 You're gonna find yourself doing a lot of things like this 0:34 where it's kinda repetitious. 0:37 And we'll cover how to make that a little bit less boring and 0:39 repetitious in a later video. 0:42 So, edit_question, edit_question, edit_question, so there we go. 0:44 Our quiz_pk, edit_question, our question_pk. 0:49 The view is going to be called edit question and 0:52 the name is going to be edit question. 0:54 Fairly straightforward. 0:57 All right, so let's go make our view. 0:59 You can probably already guess a lot of this. 1:02 Hopefully you've already built a lot of this yourself. 1:04 Login required, edit_question. 1:08 And we want to take the request, of course, we want the quiz_pk, 1:13 of course, along with the question_pk, of course. 1:18 And our question is gonna be get_object_or_404 models.Question. 1:22 The pk should be the question_pk and the quiz_id should be equal to the quiz_pk. 1:29 Now this next bit you might not have known. 1:36 You might not have found. 1:38 Asking you to build this was a little bit of a trick, I have to admit. 1:41 We need to know whether or not the form that we're gonna provide is a true, 1:45 false question form, or a multiple choice question form. 1:51 Simply because we have, I mean just like we did on the previous one, right? 1:56 But the way that we know that, we don't want to do that through the URL, 2:01 we want to do that by looking at the question they sent in. 2:04 But what we have is we have a question object, 2:07 not a true false question object or a multiple choice question object. 2:10 So how do we do this? 2:15 Well we use a handy little python function called has atter or has attribute. 2:17 So if has atter question, so if the question 2:22 has an attribute named truefalsequestion, 2:27 then form_class should be forms.TrueFalseQuestionForm. 2:33 Otherwise, form_class should be 2:41 forms.MultipleChoiceQuestionForm. 2:46 And so the reason for 2:52 this is that true false questions have a true false question form attribute. 2:54 And multiple choice questions, they link to one of these things. 2:59 Right? 3:02 So we're just checking to see if that thing is what it is. 3:03 So okay, so now we're gonna do form = form_class and 3:08 the instance is going to equal the question. 3:13 Just like we did before. 3:19 So, this is all exactly like we've been doing so 3:22 far on building out our edits and creates and all that stuff. 3:24 And let's just go ahead and do the saving part. 3:30 So if request.method is equal to POST, then form 3:33 = form_class and let's, just to show that this works both ways, 3:38 we'll do request.POST and the instance equals the question. 3:44 If you're doing this professionally, even if you're just doing this for 3:50 yourself, you want to be consistent. 3:52 You don't wanna flip flop between these different methods. 3:54 I'm doing this as multiple different ways so you can see all the ways that work. 3:57 But in the real world, for your actual job, or for stuff you're building to try 4:01 and get a job, or for stuff you just wanna build for yourself, be consistent. 4:05 If you're gonna do request.post instance equals, always do that. 4:09 Don't flip back and forth between instant sequels, data equals, and 4:13 request op post instance equals. 4:16 Bad idea to go back and 4:18 forth, you'll completely forget what you're trying to do. 4:20 So, if form is valid, then we just wanna call it form.save, of course. 4:23 And then, we'll do messages.success request, and we'll say, Updated question. 4:31 And we'll return HttpResponseRedirect to form.instance. 4:38 We don't even need that, 4:46 we can just go right back to question.quiz.get_absolute_url. 4:48 All right, and then, no matter what here we wanna return render request. 4:56 And we're gonna do our question_form. 5:02 And we wanna send through the form. 5:07 And we should probably send through, that's probably enough, actually. 5:12 Let's, let's just see. 5:17 So we're gonna send through the form and we have to close that. 5:18 All right, so question form, I bet we can edit this a little bit. 5:22 So we can do, we want to do form.instance.prompt. 5:27 And the default would be new question for, 5:38 I don't know if we can put quiz title in there or not. 5:41 We'll find out. 5:45 And instead of quiz.course.title we want to do form.instance.quiz.course.title. 5:48 No, let's not do that, let's just send the quiz through, that'll be a lot cleaner. 5:57 So come back over here to our views.py, we're sending it through the form. 6:02 That's why it looks weird. 6:10 We're sending through the form, let's also send 6:11 through the quiz, which should be question.quiz. 6:16 There we go. 6:28 Okay. 6:32 So what we wanna do is we want to do form.instance.promt 6:34 which form that instance is our question. 6:39 We could send the question through if we wanted. 6:41 We want the quiz title to be in there though. 6:44 And here we want form.instance.prompt, 6:46 and the default would be the make a new question. 6:52 And the rest of that, I think, is the same. 7:02 But we need to add a way to edit a question, so here's our question.prompt, 7:05 and let's add, let's actually update this so it looks a little bit nicer. 7:10 I'm gonna add in a little bit more stuff here so 7:16 let's add in a UL on the class of no bullet and inside that for 7:21 question in step.question_set.all. 7:28 You don't have to do all this HTML if you don't want to. 7:33 I'm just doing this cuz I want things to look a little nicer. 7:35 We're gonna do h2, and we'll do question.prompt. 7:39 And then we don't have any answers yet, but I'm gonna just go ahead and 7:46 get us ready for that. 7:51 For answer in question.answer_set.all and then we can go manually, 7:54 make them in the admin if we wanted to. 7:59 End that for a div class="callout" and 8:00 then we'll do answer.text. 8:09 That ends that, and then we'll say if user.is_super user, 8:15 eh, let's just do is_authenticated, we don't care about them being a super user. 8:20 Then we'll do an href to url courses:edit_question. 8:27 The question pk will be question.pk. 8:38 The quiz pk will be step.pk. 8:42 And we'll just put in edit. 8:51 There should be a class here of button. 8:52 And now, we should be able to get rid of that, and 8:58 we just need to close our endfor. 9:02 Oh, and we need to close our endif. 9:07 All right, cool. 9:12 So, we have our question_form, we have our quiz_detail, so let's go refresh this. 9:16 What can be in a string? 9:22 It's a little big. 9:23 We can play with that later. 9:25 But here's our Edit. 9:27 So if we hit Edit. 9:29 I'm typoing things all day long, huh? 9:32 Courses. 9:35 Refresh. 9:39 Default requires two arguments, one provided. 9:41 So, I think the problem is that we've got this multiple thing in here. 9:44 So, let's just get rid of that. 9:47 So our question form, instead of having this, we'll just say, new question. 9:49 And we'll refresh that. 9:58 So, this says what can be in a string, what can be in a string here. 9:59 But if we were to go back to our Review: Strings and Things, and 10:03 we'll say New True/False, we still get the Make a new question and the new question. 10:08 So things are good. 10:13 Let's go make sure that we can actually edit our question. 10:14 So, we'll say, what all characters can be in a string? 10:18 And, yeah, we want to shuffle the answers this time. 10:23 So we'll save, come back and edit this, make sure. 10:26 So, it didn't save our shuffled answers, and 10:29 the reason is because we're only getting our actual question. 10:32 So what we'll need to do is inside here, we need to change question, so 10:36 here question should equal question.truefalsequestion. 10:41 Also I need to fix that typo. 10:45 And here, 10:51 we would have question=Question.multiplechoicequestion, 10:54 and let's see if that fixes it. 11:02 So I'm gonna hit shuffle answers, and I'm gonna hit save. 11:07 Now I'm gonna hit Edit, and there's my shuffle answers, it's fixed. 11:10 So they're great, that's how we want to fix that. 11:15 So, there we go, we have editing questions and 11:18 creating questions and we have this form class thing which is really handy. 11:21 This is a great trick to know how to do. 11:25 Views working with model form special cases 11:28 are sometimes a bit weird to deal with. 11:31 I think this is a good solution. 11:33 And honestly, I'd probably go back and replicate the form class bit, and 11:35 the other form views we've done just for consistency's sake. 11:38 The more stuff you can make generic and the same from view to view, the easier and 11:42 faster it is to create new views. 11:46 I think we have one more form and 11:48 view to make, cuz right now we have a lot of questions and no answers. 11:50
You need to sign up for Treehouse in order to download course files.Sign up