So up to now we've mostly just talked about how forms work. We've been talking about how forms work across whatever programming language you're using or framework you're using. We mostly talked about how the browsers treat forms, how we generate HTML to make forms, how posts work, how refresh works, how post redirect works, how CSRF works. That's other than subtle details, those are topics that are true no matter what you do, no matter what language you're writing, and what framework that you're using. Now, we're going to pivot a little bit and talk about how Django helps you do all those things that we just got done talking about doing. So if you look at this picture, if you look at the picture, you see that forms are kind of in the middle of this picture. That's the final piece we're filling in. And forms are connected in a lot of ways. Forms can be connected to models, they're used in the view, and they're used in templates. And so they're a very powerful part. And all the things that we've been doing as abstractions where we ran a little bit of code, and find lots of ways to reuse that code. Or we write some code that extends an object and then we add a little bit to it and then we've got some very powerful object when we're all set and done. And so that's what we're doing here in forms, and forms can be used in views, they can be using templates, and they can interact even with models. And so we're going to talk a lot about forms. There's a lot of just menial labor that just working in forms, and if you really had to build all the HTML from scratch like I did in some of those earlier examples, it's just really painful. And there's other problems too. And that is that there's just a lot of repeating yourself. We kind have one will use like object-oriented techniques and other techniques to not repeat yourselves. And it's really easy to put the HTML in for a crappy form, but why wouldn't you want a beautiful form? And so if you write the HTML, and you write some CSS, and you do kind of some crappy version of it, then you have to fix it or hand it to a designer and then they have to go fix 100 pages. There are things in Django, crispy-forms is something I'll talk about later that just like says hey I'm using forms in Django. Wait a second, I wanted them to be pretty now, and then you just make them pretty. And if you want to change how they're pretty, you can change how that works, and then you change them all the same time. And so not repeating yourself, lean on utility code seems like why would we do this? But in complex applications you just fall in love with this idea that you don't have to repeat yourself. And even though I've showed you some of the things like post, redirect, refresh, CSRF, all that stuff. It's even more complex than that, especially when you start talking about pulling data from the database, and putting it in in an edit form and then checking to see if the data is valid. If the data is not valid send back error form and give them a chance to resubmit it. If they're successful you do post, redirect, and then you send a message in the session. We've done all that in really simple. But if you really look at everything that you need to look at, it's pretty complex. And so we're not going to do all this in this first lecture, but this gives you a sense of the kinds of things that a create form where you're going to go like, a new Cat. And then you got some forms that fills different about the Cat and then you hit the save. And so if we just go through this. These are the steps you need to do to insert a Cat in your Cat database, right? So your browser initially goes and gets a GET request. And then you fill out the empty form with a bunch of fill in the blank fields. The user can always cancel out of that and get out, the user might enter some data and hit post. Now the problem is what if you have some rules about the data such as this is required that has to be at least five characters etc. You have to then send in a form back with that data to let them fix it and resubmit it again. Or if it's good, you'll go ahead and store the data in the database, but then we have to put some kind of a success message like in a session or something. And then send a redirect out and then the browser immediately comes back and gets the redirect URL, which pulls the message out, sends the page, and sends the success. And so we've done parts of this already, right? We've done parts of this already, the big part we haven't done is kind of like this middle part here where we're validating the data and have this error retry loop that we put the user back in the loop and give them another chance. Now that's the create form, the edit process where you're pulling in an existing Cat and you're going to edit their fields is even more complex. You go load up a Cat but you might have an error page because you don't get the, they're looking for a Cat that didn't exist in our database. You send out the form with the old data that they might leave, they might edit it, they might come back. They might validate [LAUGH] the data and get an error, then I have to fix the data. Then I gotta go around here until okay we got some valid data and then you store the data in the database, send out or put a message in the session, send out a redirect to a success URL. In that success URL you put out the message in and say Yay! So that's complex too and and we're going to figure that out. Delete is not as simple as you might see, and the problem with deleting things is that you can't delete with the GET request. So usually you have to do a navigate if like you see a little delete button, you click on it, you go to a delete page. It's going to load the data that you want to delete, so you can build a confirmation page. Confirmation pages turn out to be really important because there also are tricky way to convert a get to a post. But if they're asking for the wrong data, we have to send an error message. Otherwise we'll send a confirmation form that says are you sure you want to delete this? That's both nice for the user to give a confirmation. But it also then turns this into a form, and of course they're going to label the cancel. But if they click on Yes that turns into a post and it has the key. So the first thing it does is it has to load the data again from the model. And then if that date is not there, they got the wrong key, then you send an error page out. And if the if you got the right key and the user has permission to delete the data, then you go talk to the model and you delete the thing, right? And then you put a congratulations on your deletion in a session or something, then go with a redirect because you can't respond with a 200, you gotta respond with a 302. And then the browser immediately does it get a success URL, pulls the message out of session, makes a success page with the message. Now we're going to cover this a bunch of times, so you don't have to guess the first time. But I'm telling you that forms are complex. And what's cool is, Django form objects that we're going to create act like glue. They can generate the HTML, they allow for a consistent look and feel, and they allow for you to change the look and feel. When the post data comes back from the browser and a form that it created, then it puts it all in the right spot. It validates the data based on a set of rules that you say, like this has to be this kind of a thing, and that kind of a thing, or a data, or a character, or an integer, or floating-point. Whatever it is the rules are, that's all done for you and Django. And if something goes wrong, then it hands you an error form that you can send it right back to the user. It really greatly and then of course once it's validated it moves it into a model and then actually can even to the database store automatically. So the form is like this glue thing that sort of talks to templates, it talks to browsers, it reads data from browsers, it's like stuff and. And so in a way that the form is like the controller, it's like the view, it just makes your views really succinct. And you're going to love it once you understand it. So here is a simple form, and so forms live in a file called forms.py, not surprisingly. And basically just like them it looks a lot like the models file. And so you're going to see that the one thing that forms do differently is they can have these things called validators. But models have rules about max length, etc. But there are even more complex validators. And you can even write code that you have your own functions that when the form is coming in you're going to look at this one field and you're going to say I wanted two uppercase characters followed by three lowercase characters. Sorry, you didn't do what I said. That's what's called a validator. And that's when the error page goes back and it says hey, you're missing the stuff, and we'll show you how the validator stuff works. But basically you put in little lines just like you did for the model, and you're effectively defining a user interface plus a bunch of logic behind it. Now the one thing I'm not doing in this particular section we'll do soon is connecting this to a model. So you've got to say wait a sec, I'd like to make a form and I'll really mostly want to inherit from a model, you can do that. But that's not this one, that's coming up in the whole next section, but it won't be long. The form object, right? So here's this form we just made, it's got three fields in it. And this is a real simple view, it's not useful. It just kind of shows you one of the things you can do. So make a basic form, when the basic form is defined as having these three fields. And then you say form and then a call the method as_table. And so what this produces it's just a dump. The UI that looks really ugly. But basically it generates all this HTML for you, all this HTML. Input tags and we told it to do it as_table that's necessarily not initially prettiest way to do it. But all that HTML is generated from the form utility. So it can send it as a list, it can send it out as paragraphs, etc. And so this is just to show you kind of the dump. If you go to this URL do a view Source on it, so you see this stuff in here. So you define a form object, and one of the things you can do is make me HTML. And this is not a good example, we'll come up in a bit with a better example. The better example of course is to use it in a template. And so here is a template with a simple form in it, we got a form it's a post. We got some submit stuff, we got ourselves a cancel button that we put in. And we got to csrf_token, and we're going to use that form.as_table, and we're going to surround it by a table tag so that it looks a lot prettier. And so this is a far more typical way of doing it, that first one was just to dump it. And so when you do this and you sort of make the form in a get request, you make the form, and you pass it into the context. If you remember, form.as_table, that's a very, oops, come back, too far. Form.as_table came from context, came from the past invariable, and that is right here and right here. And so we make the form object which as all the fields in it, and then we pass it into our view our template, and it renders that. And so then this is what it looks like much prettier. And if you do a view source of that, as you go to this form create, and you do a view source on that you'll see it's all that same table stuff, it's the same table stuff that we had before. It's just now wrapped in some stuff to make it look a little prettier. We put a submit button, it's got a form tag, and then you can actually hit the submit button and something actually happens. So this is by far the more typical way of using a form in a template. So I talked about the create form, the update form, and the delete form. This is kind of an example of how forms can be used. Now, I'm not actually talking in the model yet, we'll do that in a bit. So I'm just going to pretend that we have some old data. And so this normally would come from the model, this old data, title, mileage purchase_date, that would come from the model normally. But for now, we're just going to like make it up. And so then you basically start a form and you pass this old data in as the constructor. That's a constructor from the basic form class, pass in old data, and give me back an object of type basic form. And I'm going to have it in the variable form, and then I'm going to pass it into context. Now you'll notice I'm using the exact same template the one I showed you before. Because the that form.as_table understands that sometimes there's data in these fields, and it properly puts the data in it, and it properly escapes the data. It understands that this is a number, it understands that this is a date, it's got all that stuff all figured out, right? And so this is how it works as you just somehow get your hands on key value pairs of the old data, you pass it into the constructor. And now you render the form and the forms library takes care putting in all that old data. Believe you me, you're probably glad I'm not showing you how to do HTML and code and all these things. And when you do can code but this is a little different because it's inside of an attribute. You don't want to know that because you just are going to use form.as_table, and it's got all the rules figured out. This is hundreds of lines of code that you're not writing. So next we're going to talk about the validation part. So that's actually what happens when we receive data back from the browser. [MUSIC]