Handling a Form in a View10:10 with Kenneth Love
We can create forms and show them to users, but for forms to be really useful, we need to be able to process them once they're submitted.
In our last video, we handled showing a form, when someone requested a view. 0:00 This is known in HTTP parlance as a get request. 0:04 When we submit our form, though, 0:08 we don't want to put information into the URL, which a get request would do. 0:10 We want the data to be safely transmitted behind the scenes, in our HTTP headers, so 0:14 we'll use a post request. 0:19 That means though that we have to do a bit of extra work in our review 0:21 to process the form. 0:24 But hey, I know that we can do it. 0:26 Okay, so we should be all done with creating our form, 0:28 our URL, and our HTML template. 0:33 All the work we have to do now should be just inside of our views. 0:35 If we come here and we let me refresh this just make sure its good and 0:40 we put in a name and an email address and a suggestion like cover pyramid and 0:46 we hit submit like nothing happens right? 0:53 We can come back over here and we see that we just got a post, and 0:57 I gave it 200, because our view doesn't care. 1:02 Anytime a request comes in, get, 1:06 post, put, delete, patch, whatever, our view doesn't care. 1:10 Our view just goes to the exact same work every single time, no matter what. 1:14 So we need to make it were our view pays attention to the kind of 1:19 request that comes in. 1:24 So, let's go here and let's add, let's just leave our form like that for now. 1:26 And then we'll do an if. 1:34 And we'll say request.method is equal to POST. 1:37 And it'll always be all caps like that. 1:41 So if a POST request comes in, then we want to do something different. 1:43 What we want to do here is, we want to do form equals forms.SuggestionForm and 1:48 we want to give it the data from request.post. 1:55 So what this does is it takes all of the form data that comes in and 1:59 puts it into the form, and where the keys line up. 2:03 So request.post is kind of like a dictionary. 2:06 It has keys, and the keys have values. 2:10 So where the key, Name is, 2:13 or where the key Email is, it'll put that into the form. 2:17 So it just fills in the data from the request. 2:21 So that's cool, that's handy. 2:24 Now we need to make sure the form is valid, that they gave us good data. 2:26 So if form.is_valid, then we need to do something. 2:30 Let's just print right now, we'll just say good form and 2:37 then we won't run anything else. 2:41 We'll just leave that alone and 2:43 so then, that should be it for right now. 2:47 Okay, let's just stop right there for right now. 2:51 So if it's a post then it's gonna check to make sure it's valid. 2:53 And if it's valid, then it's gonna tell us good form. 2:56 So let's try this again. 2:59 And we'll say Kenneth and email@example.com. 3:00 And we'll say Pygame! 3:04 Cuz a lot of people want Pygame. 3:07 So submit nothing's going to change on the site except for 3:09 you see our data is still in there. 3:14 And if we look here it printed out good form, so awesome, we know that it worked. 3:16 So what I want to do, is I want, when somebody creates a suggestion, 3:21 I want it to send me an email. 3:25 And so to do that there's a couple of pretty easy things that we can do. 3:27 So first of all we need to send an email. 3:32 So we need to go to settings.py and 3:35 it's way too much to ask that you all, and even myself, actually send emails. 3:39 So Django has some handy built-in email backends that we could 3:45 use and we can send emails just into this little console here or 3:50 we can do what I'm gonna do in this one, we can send emails into a file. 3:55 So we're gonna make a new setting here, EMAIL_BACKEND and it's going to be 3:59 django.core.mail.backends.filebased.Email- Backend. 4:04 That is a lot of words. 4:08 And then we have to give it a file path for 4:14 where to put the files that it creates for each email. 4:17 So we'll say EMAIL_FILE_PATH. 4:20 And that's gonna be os.path.join(BASE_DIR, 4:23 which is a variable we set up at the top of this file and suggestions. 4:27 And Django will create this folder for us, 4:35 we don't have to create this folder ourselves. 4:37 So that's all we have to do here, so that just puts 4:38 the emails into a really handy, really nice file format, okay? 4:44 So now, let's come back over here to our views and 4:51 up here in our imports we need to do a couple more imports. 4:55 So I'm gonna get a couple things ready. 4:59 Let's do from django.contrib import messages 5:03 from django.core.mail import send mail, 5:07 which is a really handy little function for sending mail. 5:12 From django.core.urlresolvers import reverse. 5:15 And from django.http import 5:23 HttpResponseRedirect. 5:28 All right, so these are things we're gonna need in just a little bit. 5:32 Let's minimize this down again. 5:36 All right so, now, right in here, where we've been doing this form, is valid. 5:38 Let's see about sending our e-mail. 5:43 So, the first thing we do is we call, send_mail, and 5:46 send mail requires a lot of argument, so I'm gonna do multiple lines here. 5:50 So the first argument that goes into send_mail is the subject. 5:54 So we're gonna say, Suggestion from and a placeholder. 5:58 And we're gonna fill this in with form.cleaned_data. 6:04 This is the good data that comes out after the form is validated. 6:07 And we're gonna put in name. 6:10 All right? 6:14 And then we put in the body of the email, so 6:14 this will be form.cleaned_data['suggestion']. 6:17 And then we put in the email address that it's from. 6:25 So we're gonna put in the name and the email. 6:30 This might be a slightly different way of using format that you haven't seen before 6:35 but you can feed it a dictionary and 6:38 it'll use the dictionary keys to fill in these names here. 6:41 And form.cleaned_data has a field called name and a field called email. 6:45 And then finally, we put in who it gets sent to. 6:50 So I'm gonna send it to myself. 6:53 But since this isn't actually going to go anywhere, it won't matter. 6:56 All right, so that does the sending mail, and 7:01 then I also want to send them a message on the website saying thank you for 7:02 your submission. 7:07 So we'll use the messages part of Django, 7:09 which lets us just put flash messages up onto the screen. 7:11 And we're gonna say add message. 7:15 And we're gonna put in request, 7:17 messages.SUCCESS cuz they successfully gave us a thing. 7:19 And we'll say, thanks for your suggestion! 7:24 And then finally and you're gonna get used to doing this a lot. 7:29 We're gonna return HttpResponseRedirect and we have to tell it where to go. 7:33 So we're gonna reverse the URL to suggestion. 7:40 Let me make sure I named that correctly. 7:43 Yep, all right and so what reverse does is 7:45 it goes to your URLs.py finds the URL that matches the name and 7:48 the arguments you give it and figures out the URL that comes from it. 7:52 Okay, so we already have this. 7:56 If it's a post then we're gonna do all this stuff. 7:59 We're gonna send the email, we're gonna send a message, and 8:00 then we're gonna redirect to somewhere else. 8:03 That redirect will be a get request, and so 8:05 we'll get a blank form instead of a form that already has some values filled out. 8:08 So let's just go ahead and submit this again. 8:15 And if everything worked. 8:17 I don't know, maybe I don't have the messages on there yet, but 8:19 let's look out here and let's refresh this. 8:23 And we should see suggestions, and then right here is a time stamp for 8:28 this thing and it's a log, it doesn't know what it is. 8:32 Let's rename this to .TXD. 8:38 And it should be able to show it to us. 8:42 Close those let's open this file again. 8:47 There we go. 8:49 All right so we can see it's from firstname.lastname@example.org. 8:50 WIth the name of Kenneth and it's going to me at teamtreehouse and 8:54 the suggestion was Pygame. 8:57 You could obviously expand on this a lot further if you wanted to. 8:59 And so our message didn't show up and I'm really not sure why. 9:03 But I'm gonna add in a snippet for that. 9:08 And then we will refresh our thing. 9:12 Cuz this is just way too much code for me to type on camera. 9:18 So let's refresh. 9:23 There we go. 9:24 Thanks for your suggestion, and 9:24 we've got a little close button that doesn't do anything. 9:26 All right, cool. 9:28 So this'll be in the workspace if you wanna launch the workspace and 9:29 see what's in there. 9:34 This is all explained in Django's documentation. 9:35 I'll put a link to that in the teacher's notes. 9:38 There's a really common shortcut of creating a form with request.POST or 9:41 None, and then checking the validity of the form. 9:46 If it's invalid, you're in a GET request, at least, that's the idea. 9:48 The problem is that it's 100% possible to have a completely valid blank form. 9:53 It's also possible that the request wasn't a POST. 9:58 Both of these things leave your view in a somewhat ambiguous state. 10:01 Its better to be explicit like our if that checked the requests type, 10:04 than to hope you remember your edge case, 10:08
You need to sign up for Treehouse in order to download course files.Sign up