Welcome back, everyone, to this lecture or begin understanding had actually code out a single form,
starting with the basics of the form class.
So we're going to create a new Jingle project and Django app and then use Django forms instead of manually
creating an HTML form.
So what we're going to do is quickly cover the steps that we're going to perform this lecture.
The main idea being we want to create a car rental review feedback form.
So let's imagine we decided to start a car rental company, and we need a website to create feedback
on the experience.
Maybe things like first name, last name and email and then some sort of text feedback.
We're going to do in this lecture is create a new project, an app and then create the connection for
the templates, views and URLs.
Those first two steps, we're going to go through them pretty quickly because we've done a bunch of
times already.
Then we start onto the new stuff, which is creating a form stop profile.
Then we create a general form class and site forms that pie.
And then finally, we connect the jingle form to the view for context insertion inside the template.
OK, let's get started and head over to the text editor.
OK, so let's get started here.
I'm going to use Django Admin to create a new project, so I'll say Start Project.
I will call this my site and then I will seed or change directory into my site.
And then let's start a new application.
We do this with Python.
Manage that Pi Start app and I'll simply call my application cars.
All right.
So I have my site and then I have cars and my site.
So inside of cars, what I'm going to do is set up my template folders, so I'll say templates and then
inside of templates create a new folder.
Shares the same name as the app cars, where essentially it's going to have two pages, a review form
page and I thank you page.
So I'll create two new files.
One will just be the thank you page.
So thank you to each HTML and the other one's going to be in you.
File here.
Let's just call it maybe rental review each HTML.
So two HTML files.
Let's now connect those two views.
So kind of working your way backwards here.
So now I have views.
Here, I'll create two simple views a rental review view takes in a request and it simply renders back.
So return the render of.
And this is going to be the request along with cars, forward slash and then rental review the HTML.
Obviously, later on, we're going to actually edit this quite a bit to accept the form.
So we'll just leave it like that for now.
And then let's create the thank you view.
So thank you request.
And this is just going to return the render for the request.
And this is cars forward slash.
Thank you.
HTML.
OK.
Two very simple views here.
Now, let's connect them to a URL.
So we'll go back under cars new file URLs that pay and then we'll say from Django Dot URLs import path.
And I'm actually going to give this an app name.
That way, I can use URL name tags later on.
And this app name is going to match up cars.
We create our URL patterns list.
Hopefully, it's all feels like review.
And then here we just add in the paths.
So the first path will just be rental review forward slash.
And this gets connected to the rental review view.
So that means I need to say from.
Dot import views, so I can actually call those view functions, so then we say views dot.
And then I have rental review.
Let's give it the name rental review and then comma add in a new path here, and this one will just
be the thank you path.
So thank you.
Oops.
Thank you.
Forward slash.
And then this one's going to be vieuxtemps.
Thank you.
And just using Tab to autocomplete here.
Name will just be.
Thank you.
All right.
So I connected those views to some URLs through patterns.
I need to connect all these URLs to my project level URLs.
So we come to URLs that pie at a project level and then I need to remember to import include.
And then I can say the following I can say Path.
Let's go.
Cars as the domain name extension.
And then what we're going to say here is include.
Cars dot your URLs.
All right.
So now this should be connected in a way that I can go to my domain dot com forward slash cars, forward
slash.
And then I have essentially only two pages that exist.
One is four slash rental review.
The other one will be forward slash.
Thank you.
And I expect somebody to fill out the form.
Hit submit and then go to the thank you page.
And then the last thing I want to do is to make sure my applications are actually connected at the project
level.
Remember, we have our apps that PI file created for us with the car's config.
I need to add that to my actual settings that pi file.
So also remember to save all the changes we've been doing.
So if you ever see a little dot here, make sure to save.
So we have our cars config, which means I can go to settings about PI and just come here and pass in
cars.
The apps, the car's config.
And don't forget that on let me double check that it's cars, plural here under apps and yes, it is
cars config settings like pie cars, the App Store config.
OK?
Save that change and just to make sure everything is working.
I want to make sure that I can add a little bit of HTML here.
So we'll say Doc to autocomplete that or create heading one that just says rental review form page.
Later on, we will add a form here.
And then under thank you, I'll do the same thing, Doc, and we'll just say heading one.
Thank you.
And in fact, that's all I'm ever going to say here.
So this is pretty much done.
I just want this to say thank you.
Let's run our website and make sure it's all working.
So Python managed not pie run server.
OK, looks like we don't have any typos yet, and let's check this out.
All right.
So it looks like rental review form is working.
And now let's go to forward slash.
Thank you.
And it looks like thank you is working.
OK, so our templates are set up.
Now it's time to switch gears to forms.
So let's go ahead and do that.
Now, typically what I would have to do is come to rental review that each HTML.
And then go through the kind of tedious process of setting up an HTML form and then say, OK, I want
to be able to post information here.
And then after that, I'd have to make a series of labels as well as a let me just and do that, as
well as a series of inputs.
And I would need to do that for every single field I was interested in and collecting.
Now, with jingle forms, it's actually a lot easier.
So the first step is to still actually put in an HTML form.
So there's two things that Django technically doesn't take care of for you.
It doesn't take care of the actual form, each HTML tag, and it will also require you to pass in the
actual submit button.
So these are the only two things you need to worry about providing as far as each HTML is concerned.
It's the form tag and then the input to say submit.
And as a quick note, I should mention that Django documentation on forms in particular is absolutely
fantastic.
So I would highly recommend you take a little bit of time just to go through the Working With Forms
page in the documentation.
It's absolutely wonderful.
The whole Django documentation is already really good, but this one really just takes the cake on how
well it's explained.
They talk about HTML forms and general get and post as HTP methods.
And then they talk about how Django Forms comes into play as far as how it works for rendering.
And essentially, what happens behind the scenes is Django is going to try its best to automatically
generate these label and input pairs for you based off fields.
And there's essentially a class called a form class, where each attribute is then a field which generates
what they like to call an HTML widget, which is kind of a label input pair.
So eventually, all you end up doing is after you create your form.
Class is your code ends up a lot cleaner on the HTML side of things because you just pass in this little
form along with a CSR token, which is also automatically created for you.
So essentially, your team cleaned up a lot and all your forms just end up looking something like this.
Of course, there is going to be more to it than that.
And later on, we'll learn more about this and how we can actually loop through the fields of the forms.
But for right now, we're just going to do something simple like this.
OK.
So how do we do that?
Well, we started to come back to our application and create a new file, and this file is going to
be called Forms Dot Pi.
And this essentially follows really similar patterns to models that Pi remember and models that PI.
You had this models and then you said models that model and you created your own model class.
It's almost the same for forms that PI as well.
Except this time we should be thinking about creating this in terms of forms with fields and label inputs.
So let's go ahead and show you how it's done.
We're going to say from Django import forms kind of in the same way we said from Django import models.
And then after that, we're going to do is create our first form class.
We say class.
And then you typically by convention, say your own custom name, followed by form.
So this is our review form and then you inherit forms that form really similar to how you inherit models
that model.
And you can tell there's a lot of connections here between models and forms.
And later on, we'll see.
There's actually a special model form that even more closely connects the two.
So then after this, for every HTML label input pairing you want, you create an attribute inside this
class.
So for example, let's imagine I want to collect the first name of whoever is leaving a review.
So I create an attribute.
I call it first name and then I say Forms Dot and then the specific field that I want to have related
to the HTML.
Now, for example, I can see there's character field.
And if you're wondering, how would I know which field to use?
That is something you typically end up having to look up in the documentation.
So what you do is after a while, once you feel more comfortable with figure out how forms work in general,
you come to the documentation under form fields.
And if you scroll down here, you're going to see a list of all the built in field classes.
There's an email field, a float field, image fields, Boolean fields, time fields.
There's even things like calendar widgets, et cetera.
A lot of these just are essentially mappings from models to fields to the HTML label input pairings.
So just keep that in mind as you get more familiar HTML forms and the label input pair types.
You'll see that, OK, there's a bunch of classes that are related to that.
And essentially, each of these fields, for example, character field, we're going to discover later
on that it's actually connected to what Jingle calls.
A widget so I can see here that I have this character field.
And later on, I'll see that it actually generates a text input each HTML widget, which essentially
saying, OK, the input type is going to be a text input type.
So that's what that's trying to say.
You can click on text input for more information and how it actually works, but it essentially says,
OK, you create a character field attribute, which is what I just did here.
First name is equal to forms, not character field.
And then you end up doing, is you kind of close this off and you can actually provide a label for this?
So the label could be something like first name.
And as you may kind of guess here, that's actually going to be an HTML label type generator for you.
And you can also generate things like validations like I want the maxlength to only be 100 characters
or something like that.
So once you create this actual character field, what happens is that ends up being connected to a widget,
and that widget is called text input.
The widget itself is going to be the thing that actually renders the HTML.
You can see here this is now text input class.
And this generates automatically input type is equal to text.
Later on, we're going to discuss widgets and a lot more detail to give you a lot of customization.
For example, I can say, OK, this particular widget let it have a red border, for example, but that
just gives you the idea of how this is actually working.
You start off with the fields that connects to a widget, which later renders the actual HTML.
So it's a couple of steps of a process.
For example, you have this email input widget, which is going to be the thing that generates input
with type email.
OK, so just give you an idea of what's possible here, let's create a couple more, let's say attributes
which eventually are field label pairs here.
So I'll say it last name is equal to forms, so make it also a character field or say label labels equal
to last name.
And let's also give this a maxlength, let's say, 100 characters.
And let's also carry an email field, so we'll say emails equal to forms dot and this time I'll say
email field.
And let's give this the label of.
Email.
OK, so I have a very simple review form have their first name, last name, email, I should probably
also accept their actual feedback.
So let's create one last field called review, which is their actual text review.
And we'll have this be a character field.
And then we'll say label is equal to something like, please write your review here.
OK.
So please write your review here.
I'm actually going to see that there's several limitations if I just use the default widgets, so we'll
see that later on, that is actually going to be a really ugly looking field or form.
But for right now, we don't need to really worry about that.
OK, so major step done.
I have my review form, but the question is how do we actually take this form?
Pass it into my view so that it shows up here inside the HTML?
How does that actually work?
Well, what we need to do is come back to views that pie and be able to import the form I just created
there.
So at the very top of this, what I'll say is.
From the forms import and then you can begin to import the forms you created, such as a review form,
and then what I'm going to do is set up a situation here where I have to check whether or not they're
submitting the form so they could be passing in a post request, in which case I need to check the form
contents.
And if they're all valid and OK, then I take them to the Thank You page.
Else then, I just need to really render the form.
So let's start with the easier one, which is elsewhere into the form.
So to do this, I'll set up my if statement.
So I'll say if I request that method is equal to post or equality, then I'm going to do something.
And then here else, I'm just going to create the form.
So I'll say else form is equal to an instance of review form.
And then I need a pass in that actual form to show up inside rental review that each HTML.
So to do that, I can simply say context is equal to and then pass in the dictionary here.
Form colon form.
So all this is saying is, hey, I'm passing in some context.
Go ahead and pass in the form.
So I'm actually passing in this special form object, which is created from this class, which we already
know renders widgets, which renders actual HTML.
Then what I need to do is inside the HTML file that accepts this form is just follow the instructions
on the documentation, which is essentially just with two sets of tag layers pass in the form.
And this essentially generates a bunch of labels and inputs pairs for you.
Now remember, there is a security aspect where we don't want anybody to just kind of copy and paste
this form and maliciously send it out.
So for that, I can automatically create a SRF token, which is a special token only for that particular
session.
Essentially, that instance where the user is viewing that page to do that automatically through Django
is just a tag where you say, See us f.
Token, and if you forget this, Django is essentially going to warn you saying Caesar are, you know,
invalid or not passed, etc. So it may actually even say, hey, remember to put in the token or something
like that?
All right.
So now all your forms are going to look something similar to this where you have the token and then
you just pass in the form and all the heavy lifting of this line 12 is done for you within Django.
Save the changes and come back to views to finish this off.
So the second one or a second step already done?
If they're just visiting the page for the first time, go ahead and create the form and then pass it
in as context.
Now what if they actually hit submit on that?
So if they actually hit submit, that means they're saying, OK, post method initiated, then in that
case, I can actually create a, for instance, and automatically populated with the data from the specific
request.
This is done by saying form is equal to review form and then you pass in the actual request, which
you know, is essentially going to match exactly the labels and inputs because it's the same form that
was originally rendered there.
This is probably kind of one of the confusing syntax codes, but you can think of this as just hey there
to fill out the form now actually pass it in to Django to check if it's valid.
Speaking of which, the next step should actually be checking if the form is valid.
So say if form underscore is, or excuse me, if form dot is underscore valid.
So it looks something like this, you have this little extra check.
And this is essentially Jango checking automatically things like, OK, did they actually pass?
An email to the email field was the first name short enough was less than hundred characters, et cetera.
So you check if the form is valid.
In that case, you can actually later on do things like save the form to a model if it's a model for
before right now.
Well, we're going to do is just print out at the command line, the actual form data, which is form
dot cleaned data.
This actually ends up being a dictionary you can play around with.
You'll see later on, but it looks something like this.
It's essentially saying something like first name colon.
And then what was passed then by the user could be something like, you know, Jose.
And it does that for last name, email review, et cetera.
And then after that, so they just submitted the form we get to do whatever we want with the form,
and then it's up to us to redirect them to another page.
To do that, I'm going to redirect them to the thank you page, which means I need an import redirect
as a shortcut.
And then I'm also going to say from Django that URLs.
Import reverse.
So remember, inside my URLs that file I have thank you as a name here.
So I'm just going to say, look up the cars.
Thank you.
Your URL pattern and then go to that view.
That's a reverse lookup, as we discussed earlier.
So how do I do that?
I simply say the following I say, OK, return a redirect to a reverse lookup of the URL cars underscore.
Thank you.
And then save that change.
OK.
So kind of a lot here.
Let me zoom out so you can see everything at once.
But what we've done here is after we create this form class, we go ahead and import it into our view.
Notice again, I'm importing that actual form.
Then you check, Hey, are they actually posting something?
If so, pass that information into the review form.
And if it's valid, then I can do whatever I want for the information by accessing it through what's
essentially a Python dictionary.
And then here I'm going to redirect them.
So will we actually see the information here inside our terminal?
Otherwise, it's the first time visited page to have a hit, submit the go ahead and just create the
form and then pass it in here as context of the page.
Which then means if you come back here to run to review that HTML, that's being passed in here into
the form and looks like we have a small typo here.
This is just the autocomplete that messed me up.
So we have form action is equal to post.
This really should be method is equal to post.
There we go.
We actually don't worry about action that's taken care of us through the rerouting in Django.
But again, this should really be method as equal to post as essentially stated here.
Hey, request, that method is equal to post.
All right.
So let's go ahead and check this all out that it's working.
What we're going to do is just go to our rental review page and you should see a H.
HTML form there now.
So if you come to rental review, you're going to see a pretty ugly but workable H html form.
So let's actually pass on some information.
So we'll say first name, last name, email.
This does have to be something that looks like an email, so we'll say gmail.com and then we'll write
a review to the car was great hit submit query and it took us to the Thank You page.
So did this actually work?
Well, remember, we're not actually doing anything with that information, except inside of View's
remember.
I said, OK, the form is valid.
Go ahead and print form that clean data, and I can see it was printed out here.
So what is form that clean data?
It is a Python dictionary that gives you a lot of power over the sort of things you can do.
If that information, if you really want it to, you could then just import this or inject it straight
into a model.
Later on, we'll see that there's actually a much better way of doing that using a model form class.
But that is the kind of very basic elements of an HTML form being generated by Django.
OK.
Coming up next, we're going to do a lot more discussion of certain details, especially considering
widgets and how to make that forms look better in general or better in general.
OK, I'll see you at the next lecture.