Google has a bunch of different APIs. It can be tricky to figure out how to incorporate them into a Django project.
We just released a course on the freeCodeCamp.org YouTube channel that will teach you how to build a Django app that uses multiple Google APIs.
Bobby Stearman created this course. Bobby is an experienced developer and has created many helpful courses on his YouTube channel.
The APIs included in this course are the Google Places API, Google Maps API, Google Directions API, and more.
Here are the sections covered in this course:
- Setting up and enabling Google API's
- Setting up Python and Django
- Backend development such as models, views and urls
- Testing our new app
Watch the full course below or on the freeCodeCamp.org YouTube channel (2-hour watch).
Learn to use a Django with six different Google API's in this core from Bobby Stearman.
Hey, everyone is Bobby from decoding here.
And in this course, I will be walking you through and showing you how to build a Django app that uses six different Google API's.
So let's start with the walkthrough.
If you look at my screen, you can see that I've got the app open already on the sign in page.
So if we click on sign up, because we don't currently have a user account, there's Bobby stemmen.
And we'll have a username This must be an email, Bobby at did demo.com.
password, I will use Fred Fred one.
Confirm Password, Fred, Fred one, we have also got a show passwords toggle, it converts a password input to a text input.
So you can see they match.
If I click Sign up, when I click Sign up, we will be using the recapture version three software.
This is a Google product that scores a form submission.
And the higher the score, the more likely it is that is a real human being that is actually submitting the form is great.
The fact we've got this element in the bottom right of the screen would suggest that the software is working.
So this sign up should get a message that says thank you for signing up and will then be redirected to to the user account page.
The user account, the user can then update their profile with an address.
And this is where we use the Google Places API.
So it is predictive.
So as I type into the input, Google will predict the address in the country that is predefined in settings, dot p y, and give you a number of different addresses that meet the search.
So let's go with 123.
And that's coming up with a few different addresses this go 123 Victoria Street, as I click it, it will pre populate some hidden inputs.
And then I have the option to update.
Your profile has been updated.
Okay, so that's one of the API's.
The other one is in route.
So this app will allow you to put a starting point, so an origin, a waypoint, one, a waypoint, two and the destination.
And when we submit this, or actually, when we finished the fourth input here, programmatically, it will create a parameter string and redirect us to a different URL, and it will render the map.
So let's add a few addresses.
So we'll go one, high streets, Sutton eally, they'll have another one high one High Street, had them easily.
So this is all around my local area.
Then we go one, High Street, stratum ealey.
And then lastly, we'll do one marketplace.
There we have it.
When I click this, it will then say right, you have completed all four waypoints.
And if you look at the top here is create a fancy parameter string, but the URL is map.
So it shows the start and destination longitude and latitude, the duration from the origin to the destination, the distance between origin and destination, and then it will render a map, which is brilliant.
And if I then click, click here for directions, it will then unhide some elements in HTML.
And it will show you every single step that is required from the origin to the destination.
So that is the application that I've built.
This is the one that we're going to go through in this course, I will go through every single step that is necessary, right from enabling API's at Google and recapture starting a new project, building the back end building the front end and fully testing the application.
So without further ado, let's jump into section one.
Hey, everyone is Bobby from decode in here and in this segment, we will be setting up to Google API keys.
These API keys will allow us to interact with six Google API's.
The first one we'll be looking at today is something called google recaptcha.
Now, this is software that stops malicious software from interacting with your website.
So essentially, it keeps the riffraff out, and allows real human beings to submit forms.
Now you will have come across this before in other people's websites, you will complete a form and when submitting that form, you'll be presented with Nine images and asked to select any image that may contain a bus, or a plane or a motorcycle.
And if you select the right images, you can then submit the form that is a challenge based form submission.
And this is version two, we won't be using version two, today, we'll be using version three.
Now this is not challenged based.
Instead, Google scores each spawn submission against certain criteria.
Now, the higher the score, the higher chance it is, that is a real, live human being some in the form and not some malicious software.
So that's what we'll be setting up today.
So let's jump straight into it and set up recapture.
So if you look at my screen, it opens up in google.com, slash recapture slash about on this page, you will find all the information that you need to find out a little bit more about recapture.
But what it does some use cases and also the history because it has evolved over the years, when on this site, ensure that you've got a Google account, you will need one, click on the V three admin console.
You can see here that I've got six sites, I've been using this for some time, and a lot of my clients like to use recapture.
But whether or not you've got this set up on your machine already, you do need to follow this process.
So you need to click the little plus button here, which, which is to create a new site.
So let's create your site.
And we will call it Google Django tutorial, we will nkuku reCAPTCHA version three.
Again, it says verify request with a score.
This is what we want version two verifies request with a challenge.
So we'll click on version three.
And then you need to add the domain.
So we're doing this in a development environment.
So it's on my local machine, and we'll be using Django.
So the domain in this case is localhost.
You don't need to put the port of a spa that right now I have a local post.
And then click Accept.
There we have it.
So it creates a key and a secret key are working with API's.
If you've done this before, you will know but if you haven't, I like to look at the API keys as this.
an API key is the equivalent of a username.
And API secret key is an equivalent of a password, just try to keep them secret, because you don't want people getting hold of your keys and making calls fictitiously.
So there's copy the site key, I like to just dump these in a notepad so I can use them later.
I've got one open here.
So we capture underscore key equals, and we'll paste in the key back to the website.
We'll copy the secret key.
And we'll dump that here as well.
You can see here I've got another one called Google equals that's the API key we're now about to set up.
That is all we need to do to set up recapture.
The rest is done in the code in Python, or in this case, the Django web framework, which we'll be setting up in the next segment.
So we'll continue now.
And this is the website.
You will need a Google account.
You can see I've got my icon there, my logo, and setup is decoding.
When set up on Google, you need to click on console.
It will take you to your console home.
And then you need to set up a new project.
So if you just sit Look what I did there.
on here, just click the pulldown list.
And then you can set up a new project.
And we will call this Google Django tutorial.
And then when it's finished doing that, you can then select the new I was just doing it's doing its magic.
only take a second.
Okay, that's complete.
So now click the project that we just set up.
And this is the new Google Django tutorial home.
You now need to click on API's and services.
When in there, you do have the option to click Enable API's and services.
But first off, we need to click on credentials we need to set up the API key click on click banjos.
This will be an empty blank slate, we now need to quit click on Create credentials.
This will allow us to select different options.
But the one we want today is API key, click on the API key.
There we have it, copy the API key.
And save that in the notepad.
There we have it back to the website.
Now, we haven't named it, we can name it by clicking this little pen here to edit the API key.
And in here, you can restrict the API key to certain IP addresses.
Change the name, which we will this is Google Django.
By the time you see this tutorial, This tutorial will be dead, ie will be removed from Google.
So there's no risk here.
That is the key, we've set up the key now we now need to enable the API's.
So if we go into the dashboard, again, this option here, so plus, enable API services there.
And because maps are the most popular API service that Google provide, it's right at the top, click on View All 17 there's quite a few of them.
The scroll down is a whole bunch of different API's here.
The first one that we need to look at is Places API.
I won't go through what each of them do, specifically, but each of these in your own time, click on them, and it gives you an overview of exactly what they do.
Now places will be using that to pre populate addresses when creating an account in our project.
So you start typing an address, and it will predict what the address is that you're looking for.
And you can just select it, and it pre fills all of the address, the town, the city, the county and postcode, and so on and so forth.
And you can always pull from that the longitude and latitude, which is very, very helpful.
So let's click Enable.
That will take a second.
And now that that's completed and enabled, we now need to look for the Directions API.
So you can go back to the overview and click on enable API's and go back to the main dashboard.
But because we've enabled one now, it then gives you some options of other API's that you can work with.
So let's look look at Directions API.
So that is the Directions API, we now need the distance matrix.
We'll enable that quickly.
Some of them are quite self explanatory, to be fair.
The next one is Google geocoding.
Well, lo and behold, that allows us to geocode certain points.
So geocoding API will enable this.
There we have it.
So just to recap, In this segment, we have created two API keys.
One of them is with google recaptcha version three, this will allow us to ensure that real human beings are submitting forms on our project and stop the riffraff from submitting those forms.
This will allow us to have our users complete or start typing their address, and it will predict where they live and they can select an address.
And also they can then add two different points.
So two locations in any given country, and our project will then calculate the route and distance between those points.
Okay, that's the end of this segment.
Thanks for watching.
That starts setting up the project in the next segment.
Hey, everyone, it's Bobby from decoded here.
And in this segment, I'm going to show you everything that you need to do to start building this Google API app.
Now, if you're familiar with Django, you will know what that all means.
However, if you are an absolute newbie, I will just show you quickly, a little bit about Python and Django, and a library that we'll be using, which is virtual MV wrapper dash when in my case, because I'm using a Windows machine, so if you look on my screen, I've got the Python website open on their downloads page.
If you haven't got Python downloaded on your machine, you will need to do it, I do have a link to a video there's at the top of the screen now that will show you exactly what you've got to do to install Python and also configure a library called Virtual envy wrapper.
And that is this page here.
So it is on a repository in pyp.org.
Like I say, look at the video, walk through all of those steps, get Python installed on your machine, get virtually a V wrapper installed on your machine, and you'll be good to go.
The third tab here is the Django project.com website.
So this is Django web framework.
So it says here that Django makes it easy to build web applications more quickly with less code, that is exactly what it does.
And that is what attracted me to Django about five or six years ago, I've been using it for quite some time, it's easy to learn the documentation is absolutely fantastic.
And they've got quite a good tutorial on the actual website we need to do is click on the Get Started with Django, link here, and away you go.
But that's what we'll be using in today's segment to get started.
So what we'll do, we'll start off by opening up a command prompt.
And if you've already set up virtually a and V wrapper, then you can start using certain commands.
That's why I asked you to follow that video.
Because if you hadn't set up virtually a V wrapper, then you wouldn't be able to use the same commands that I'm going to use today.
So what I'll do straightaway, I will CD into my development directory.
And what I would do is I set up a new virtual E and V.
And the way you do that is MK virtual e m v.
And then with a space, you then name this E and V.
So we'll call this the same as the project.
So we'll go did Django Google API tutorial.
Okay, click Enter.
And that will outdo all of the necessary configuration on your machine.
And it will set up a virtual E and V.
So what I'll do, I'll show you quickly was that that has just done.
So if I click on my directories here, we go into my own.
So if we're going to Bobby, which this is the default configuration that will set up an E and V file in your user directory.
So you can see here that I've got envies, and I've just set up did Django Google API tutorial.
If I open that open lib site packages, these are all of the site packages that we Python will need to work.
So these just come straight out of the box.
So when you set up a virtual E and V, this is what you get.
We will then be installing Django and a few other libraries and they just get added every time we pip install a library.
It gets added into our virtual E and V.
So that's what we've just done by adding by using make virtual E and V.
Go back into our command prompt.
And what will now do is we will pip install Django for plus enter was asked, so I probably glossed over that what but the command PIP is essentially as a standard package manager, and allows you to install and maintain packages for Python.
So we use pip install to install certain packages from public repository such as p ypi.
And I've just pip install Django.
If I go back into my envy directory that I've shown you a moment ago, you can see now that we've got Django package here, and within Django, it comes straight out of the box, it comes with a whole bunch of different directories, and models and views and all sorts and that is essentially how Django works.
So we'll be making calls, creating models, creating views and forms.
And it all interacts with these directories and files here.
So we've now got a virtual environment all configured and Django installed, we can now start a new project.
So you need to type Django dash admin, and then call start project and then you need to name the project.
So we'll call it exactly this.
Same as the development environment or virtual environment sorry, did Django Google API tutorial? Okay, that should have done it.
So if I open up my directory again, there we go Bobby development.
And in here we've got did Django Google API tutorial, open that up.
And this is what comes straight out of the box, we've got a manage.py file.
And then we've got the main comp directory here, enable settings URLs, you got ASCII or whiskey and you've got an init, Dunder init file there.
So that worked very, very well, we now need to create our first app.
So Django will allow us to have numerous apps running within a project.
So what we need to do is open our command prompt back up, and we now need to CD into did Jango.
Google API tutorial.
And now that we've got the project there, we can now access the manage.py file.
And that is the manage.py file that is in a main project here.
So we make a call to manage dot p y.
So we say Python, manage dot p y start app.
And we'll call this one main.
I opened up my directory again, we now have an app in here called main.
And straight out of the box, it comes with a few files.
So you have an empty migrations directory.
That is what's used when we're creating models.
And you migrate those models to a database, we've got an admin file an X file, we've got models file, this is where you house all the models for the project, tests and views, we will we'll create one or two other files, but this is what comes straight out of the box.
We're now at the point where we're gonna start writing some code.
To do that, we will need a text editor, I use Sublime Text.
But there's so many different text editors out there, use the one that you like the best, and then you can start coding.
So what we'll do, we will open up Sublime Text in our directory that we just created did Django Google API tutorial.
So there we have it.
This is the project in Sublime Text, you can see we've got our manage.py file here, we've got the main project directory, which we can open up and you can have a look at these files.
And then we've got the main app that we've got here, we will be focusing our time in settings dot p y, and you are ELLs dot p y today, which is the URL comp file.
So we'll open up the settings dot p y, first and foremost.
And if I scroll down, you've got whole bunch of code here that comes straight out of the box of Django, this is very, very standard.
We do however, need to change some of this code.
And that's what we're going to do right now.
So at the top of the settings.py file, here, you have from path lib import path that is required.
But we also need another import.
This is import OS for operating system.
This library allows us to access things like environment variables, okay, and we'll scroll down a little bit further.
If this if we were building this in a production environment or for a production app, then I would do something with a secret key here, I would use libraries such as Django decoupled to remove sensitive information from the project.
But as we are not doing anything like that, and this is just a tutorial, I will just leave that as it is.
So if you scroll down further, again, we've allowed hosts that is something more for production.
You've then got installed apps.
Now these are the installed apps that come straight out of the box.
But we have created an app here called may have you look in apps, the name of this is main.
Okay, so that's what we need to reference in settings dot p y.
So if we enter a couple of times, just add a little bit of whitespace.
Just add a string called main, and then a comma, a trailing comma.
So that is selling Django that the app that we've just created is actually included in the project.
Then if you scroll down a little bit further, we've got middleware.
We won't be playing with that here.
But there are some libraries that we require or other applications require.
And they do need you to have some middleware alterations.
Routes URL comp, don't need to change that templates.
We won't be changing that whiskey application, no change, no change with database either.
Now, if I was to make this app for a production application, I would probably use database such as PostgreSQL.
But we would just be using the database that comes straight out of the box is no harm in that So, language code, it defaults to en us, I am in Great Britain, so en GB.
And then at the bottom here we've got a variable here called static URL.
Now we will be creating this app and it will be looking fantastic.
To do that, we need to be using files such as Cascading Style Sheets, or CSS and Java scripts or j s files, and also images such as logos and things like that.
So we do need to configure static files in the settings dot p y.
And how we do that is we add a variable called static files underscore does.
This is a list.
And in here, we have we call the OS library that we just imported.
path, which was also important at the top of the page.
And then we joined, and we joined the base directory.
And we call it static.
That is the only change we need to add here for static files does the static URL remains the same, but we also need one in here called static route.
There we go.
And this is OS dot path, dot join dot, then bracket and then this is again based Dir.
But this one is static.
Okay, they are the only changes we need to make to Settings dot p y in regards to static files.
We do now need three more variables.
The first one will be called Google API key.
have that as an empty string for now we need re recapture.
Cool, that recapture key again, empty, and we'll have recapture cool, his secret key secret saved with a secret key.
There we go.
And what I'll do, I'll open up the notes that I made in the last segment.
And we need our it looks like I didn't say the secret key.
But we will get that.
We'll save that now.
This was the Google API key.
There we have it.
And the secret key I'll have to get from recapture in a couple of moments.
In fact, let's do that now.
One of the sites that we were doing was this one here, Google Django.
And I believe we're going to settings keys that we have.
Okay, we copy the secret key.
Go back into our project.
And we save that and recapture secret key.
There we go.
That is settings dot p y file complete, we don't need to do any more configuration in there.
The next change is in URLs dot p y.
And what we need to do in this file is we need to have the path we need to bring it include we need from django.com.
Now when I'm referencing Django directories, I'm quite literally referencing them in the MV file.
So go back in here, lib site packages.
Remember when we were setting up the virtual environment, if we now go into Django, and in the project here, Django dot URLs.
We go into Django and go into URLs.
We're referencing these files here and functions and classes within these files.
That is exactly what we're doing.
That's how we're importing them into the project.
So from django.com import settings.
So we're now importing, amongst other things, everything that we've got in this file here.
Then from Django, dot content, dot URLs dot static, import, static that looks right.
Okay, so we need Django comes with admin.
And I've been paid already straight out the box.
But we do need to add a another path here.
And that will be to our main app URLs that we haven't added that file yet, but we will reference it now.
So is path.
And what we need to do is use that include that we've just imported.
And its main, and we'll have a file in that main app called URLs.
And then we'll use namespace equals, this will be called main.
Wonderful, they're the URL patterns that we need.
We also need one other setting in here for the static files.
And what we do is if settings dot debug, we're referencing debug, which is in settings.py, at the top, so it defaults to true.
So when when in development, when debug is true, when you have a problem with your code, or come up with the error on the screen, which is very handy, but you don't have this, you would not have debug set as true in production.
So if it is set to true, which it currently is that we need to add to the URL patterns.
And how you do that is URL add equals static, that is the library that we've got here.
And then we want settings dot static URL.
And then we want document route.
Equals settings dot static route.
And that is it.
So the settings dot static URL, that's what we set up in the settings.py file.
So the static URL, and the static route is also this one here that we set up as well.
So we have now set up the settings dot p y, and the URLs comp file correctly.
And that should now work.
One last thing before we close off this segment.
And that is the we're referencing a URL file that is not there.
So if we go into main, new file, and we'll call this you are ours dot p y, we will create the necessary list that is required for URL convert.
So we'll say from Django dot URLs, import path from Dart, so this will be referencing a views file, which is here.
Import views, so we'll be importing everything from views.
So this is what we called the app as a namespace in the URL comp, main.
And then we want you are l patterns equals, and that's an empty list.
We will add to that in another section.
Okay, so just a recap on what we've gone through today.
We have set up a new Django project, we've created a new app, we have adjusted the settings.py file, we've configured static files in the settings and URL Comm.
And we then added the URL patterns in the URL conf as well.
So we are now good to go.
We are ready to start coding this application.
And we'll be doing that in the next segment.
So thanks for watching.
See you soon.
Everyone is published and decoded here.
And in this section we'll be following on where we left off from the last one where we started a new Django project.
In this section, we will be fleshing out the back end.
What I mean by that is we'll be creating some models, or one model, actually, you know, we use a profile model that extends the built in user model that comes straight out of the box of Django.
The reason we're doing this is because we want our users to have the ability to sign up and sign in and create your profile.
This is how we will be using the recapture API and the Google Places API.
Okay, we'll also be creating some form some views and URLs and some mix ins for views.
those meetings will essentially help us make our code look a little bit easier to read.
And those mixings will be recyclable.
We can use them in other apps as well which is great.
And then we'll also be creating the template directories so this will be regarded as the back end.
So without further ado, let's jump straight into it.
You can see on my screen here that I've got four tabs open all of them on Doc's dot Django calm dot com.
Like I said in the last section, the Django documentation is second to none.
And I wanted to just go through this quickly because we are working with models, we're working with signals, model forms and views.
So for those that are absolutely, well, they're newbies at Django, this is going to be quite helpful.
So what is a model, a model is a single definitive source of information about your data contains the essential fields and behaviors of the data you're storing.
Generally, each model maps to a single database table.
So models translate to database tables.
Like I said, in the last video, we'll be using SQL lite, that comes straight out of the box of Django, you can upgrade to something like PostgreSQL.
But we're not in this app.
So when we're building our user profile model, we'll be using things called model fields.
And the most important one, we'll be using char fields and float fields and things like that.
But the most important one that we're using is the one to one field, which links the user profile to the built in user model, which comes straight out of the box with Django.
And we'll be creating the user profile using signals.
So that's models, very, very quick top down view models.
And by all means, have a good read of these docs pages when you have a bit more time signals.
So we'll be creating a signals.py file.
This will be handling the logic of creating the user profile when a user is created.
So we'll be using post save and receive a decorator.
To do that.
I'll show you what that all means when we get into it.
Next, we've got model forms.
So we are creating model form.
So this will be a model form linked directly to the user profile model.
We will also be creating two other forms these forms will inherit from some built in class forms that Django has straight out the box, one of them is a user creation form.
And the other one is an authentication form.
These forms handle the logic of signing up and signing in perfectly.
So it just means that we haven't got to handle all of that logic, we can just call form dot save.
And it does all of that in the background, which is great.
Django is all about getting as much output with as little input as possible.
So if we can get away with using some built in models and classes and forms and things like that, we will.
So yeah, like I say, we'll be using the user creation form to build a user form.
And we'll be using the authentication form to build an auth form.
And then we'll be looking at view.
So we'll be creating class based views and function based views, I do find that some tutorials online focus on one or the other.
And when you're new to Django can be quite confusing, especially if you've been focusing your attention on function based views.
class based views then look a little bit alien.
So I'm doing a bit of both in this tutorial, just to help you new newbies out there.
So let's jump straight into it.
You can see that is that is where we left off.
So if we open up our command prompt, you can see that I've got my virtual environment fired up, and I'm in the correct file.
Now, we will be working with API's.
As you know, that's the whole point in this tutorial.
And in Django, there's a great library called requests that help us out massively with API calls.
So all you need to do to install it is use the PIP command.
So pip install requests.
And that will now be in our E and V file that I showed you two videos ago.
Now what we need to do is start a new app.
So we go Python manage.py start app, and we'll call this users.
If I now look in Sublime Text, you should now see a user's directory, which is great.
It's pretty much blank, but we'll start fleshing out in a second.
So the first thing we need to do when we start a new app is going to set this dot p y and register that app in the installed apps.
So users training comm comma, and there are a few other variables that we need in settings dot p y that I forgot about in the last section.
So we'll do that now.
I will be copying a lot of code from my other screen in this section, because it will save a lot of time it will make for a much shorter section and I will hopefully be able to hold your attention for a little bit longer.
So as we are using sign up, sign out, sign up sign in and sign out logic, we will add some variables in settings dot p y is a login URL.
So this is where users will sign in.
So we haven't created this URL yet.
But we will in this section, we've got a login redirect URL, which is account, this will act as the home page.
Now, there will be a decorator.
So a login required decorator on that view.
So when somebody visits the homepage or index page, it will redirect them to this sign in page.
But that works for this app.
So I've kept in here.
And lastly, we've got a logout redirect.
So when somebody signs up it redirects that user to sign in.
So they're the three variables that we need in settings, dot p y.
And there's one last variable before we move on to the URL comp, and its base country.
And it uses that code when predicting addresses for the Places API.
So you can change that to something like fr for France, and other country codes.
So now we need to go to the URL comp file and add users to the URL pattern.
So we'll do that quickly.
Just copy it down, there's no need to always type it from scratch, or though it does help when learning Django.
But my typing is terrible.
So I tend to litter this, these apps with typos and it causes a whole range of issues.
So that is all we need to add into the URL comp file that's saved.
So it's setting so we're close those.
And now what we need to do is go into main URLs, and what what they will copy this across to users into a new file, we'll change the app name to users.
And we'll save this as URLs dot p y, because we're referencing that in URL comp, p y.
There we have it.
Okay, so now we're good to go, we are good to start the models now.
So we are not creating any models in Maine, Maine is going to be used for a few views, such as routes and map.
And users will be handling all of the authentication logic.
So we'll add the models in here.
So if I just take my code, and I will copy and I'll quite literally dump it in here, and then walk you through what I'm doing.
So the from django.db import models that come straight out of the box, and then we're installed.
So we were importing user, which is the built in user model that I keep talking about.
So you will get used to right in there.
So Django dot contrib dot auth dot models import user, I normally have that in every one of my views.
So so you get used to write that quite a lot.
We then have the user profile, which is a class and any password models dot model.
In my models, I generally have a timestamp and an updated this allows me to track when a model has been created.
So we use the auto add also in auto now add equals true.
And the updated is also now so every time a profile is created, this will capture the date time.
And every time a profile is updated, it will also create the it will keep updating this field with the new date time when it was when it was updated, then what user This is the important and this is the one to one field that I was talking about, you pass through the user model.
And then you also have underlay equals models dot cascade, I move this across it, you can read everything.
So that means if the user was deleted, then this user profile would subsequently be deleted as well.
So there's no profile in the database that isn't linked to an actual user, you can also have something like set null in there.
So if the user was deleted, this would still be in the database, but it would be null.
Next, whole bunch of char fields.
With left, these are these will be created as nouns analogous to blank users equals true because users will add an address once they've signed up.
So we have a char field for address, Max length 100, you have to have that in there a max length keyword, because otherwise it just won't work.
And we have town County, postcode, country longitude and latitude.
They're all populated when a form is submitted from the front end, which we will be looking at shortly.
Capture score that is the recapture score.
So when it for me, when somebody signs up, we will be using the recapture API to score the submission, the higher the score, the more likely it is that is a real human being that score is pass through and save to this field as a float field.
The highest you can get is 1.0.
So it defaults to 0.0 has profile is a Boolean field.
So it's a simple true false, it defaults to false.
So when a user signs up, they do not have a profile when they add an address and longitude and latitude.
This will then be changed to true.
Lastly, we have an inactive Boolean.
I always have this in my models is defaults to true but we it gives you the option to change this to false If ever you want to close a model down.
And lastly, we've got a Dunder string function, pass resell from was returning an F string self dot user.
Okay, so that is the model.
Like I say that translates straight to the database.
So when we make migrations and migrate, that will become a database table.
So that's our model.
We now need to create some forms.
So if I click add new file, and save as, and we'll call this forms dot p y.
There we have it.
So we've got three forms a user form, an off form, and a user profile form.
So we're important a few bits and pieces here, let me make it a bit easier for you to see.
So we're importing model form, like I say, we've got a couple of built in class forms that, that come straight out of the box user creation form and authentication form.
Again, we're importing the built in user model, and then we're importing form from Django, and lastly, the user profile for models that we just created.
So that's all we need in this file, we've then got the first user form, this is inheriting the user creation form.
So you what you need to do is create a few variables.
So first name is forms, character fields.
So as a char field, Max length 30.
This is exactly what the field is like in the built in user model.
In fact, then we start with the user profile form, it might make a little bit more sense.
So this is just a model form, but they're more or less exactly the same.
So address, you can see here, this address is relates directly to the user profile address field.
And again, it's a character field, which is the same as in the model, the max length is 100, that matches what the max length is in the model.
So we tried to keep model forms identical to what they would be in the model themselves, we've got required true, so this field must be completed for the form to be submitted.
And then we use visit a socket widget equals form.
And this is going to be a hidden input.
So the widget in a model form that kind of translates through to HTML elements.
So this will create an hidden input element, and it will be rendered through on the HTML file.
So you could also have text input, you could have password input, or you could have a whole range of different things.
And you can also pass through things like classes, and placeholders and things like that.
And that's how we can change the way the form looks on the front end.
Because a very, very basic form from Django doesn't look too good unless you actually add some bits and pieces, such as classes and IDs and names and then add some CSS.
So this is the user profile form, aka says a model form, we've got address, town, county, postcode, country, longitude and latitude, they will be the input elements that will actually be hidden on the HTML file, then we've got class matter, the model that we're linking this to is user profile, and then we have a tuple in fields with all of the field names.
Okay, so that's the user profile.
So I'll start there.
And then it will let make a little bit more sense when we look at uniform.
So like I say, inherits from the user creation form.
So the first name very much like the user profile form, we're using a char field max length is 30.
Because the built in user model, first name field has a max length of 30.
Again, rich required True, and in this widget is a text input, and we're passing through as an attribute placeholder is your first name, we're doing the same for last name, except we're changing the placeholder, the username is actually an email field in this case, so when somebody signs up, the username is an email rather than just a normal username.
And then we've got password one and password two.
So in this, you can see we're actually we're passing through a class as well to the attributes as because we can then toggle between a password input and a text input.
So there we have it, we are then adding a token field.
So this for the reCAPTCHA token, it will be a hidden input, but that will be capturing the token when we're processing the form using reCAPTCHA.
version three, then we've got meta class models, user and fields are, as you can see, here, they're the same as what we've got above, then we've got your form, your form is a little bit shorter with a username and password, email field, which we have a text input and a char field with a password input.
And again, by inheriting from the authentication form, that means that when we call form dot save, it does all of the logic in the background, which is fantastic.
So these are all forms, we don't need to mess around with them anymore.
That is, that is it for this project.
We don't need any more forms than that Figes, open that up there.
The next thing we need to do really is create the mix ins.
So let's go ahead and do that.
And we'll add them to the main directory to a new file.
And we'll save that as mixings dot p y.
Again, I'll bring it straight from my other screen here.
Okay, there's some pretty one of these is called directions is a function that we're going to be using to make API calls.
So these are quite important.
So we'll go through these we're bringing few through a few things are From Django, one of them is a well from the EU, this is from URL lib dot pass where important URL encode this is for a redirect function of God, which I'll go for in a second.
But you can see we're importing requests, because we'll be making an API call.
And as a few other bits got Jason daytime got format, timespan for the Directions API, and also JSON response, because we're making a mixin.
So this is the form errors.
Now I use this kind of default that I use when I'm processing forms.
So if I ever overwrite the form valid method there, and if there's an error, then we call the form errors.
And it essentially returns a string of all of the errors that you can pass through to the front end, which is quite handy with Ajax.
The next one is a function called reCAPTCHA.
And we pass through the token, this is the API call to recapture.
So the token is passed through from the front end in the view.
And we create a variable called results.
And we're doing a POST request to this URL.
Okay, so it's google.com reCAPTCHA, API site verify.
And then we create a data dictionary.
And in that dictionary, we pass through the secret as a keyword.
And this is the recapture private key that we've got in our settings.
And also the response, we pass through a token.
That is the API call is very, very easy.
And then we return result dot Jason.
So we just saw notify the response.
And that's what we use when we're creating views and a few minutes.
This is a great function.
So what this does, it uses the URL in code.
But if you pass through parameters, and the URL to this function, essentially returns a string that can be appended to a URL, and the string will look something like color equals blue.
And size equals large, okay, and that that parameter string can go, you can have a whole range of different parameters in there.
But it just means it can be appended to a URL, and then when redirected to that URL, you can do something with those parameters using request dot get dot get.
And we are actually using that in this app.
So that's a great little function that we use.
So this is the AJAX for mixin have gotten this is kind of the default mixing that we use, although I do overwrite the form valid function quite a lot.
But I've written this for AJAX call, so we can Ajax or five form submissions.
This means that on a front end, the HTML doesn't need to reload.
So you submit the form, you get the response, and then do something with it.
So I've got this as a way of Ajax of fire in Django forms.
So we've got form invalid method, and we've got form valid.
And both of them are returning JSON responses to the views that we will be using it.
Lastly, we've got the directions function, passing through arcs and keyword arguments.
Then we've got a whole bunch of variables here.
So from the keywords, we're getting lat, a long a and a whole bunch of other longitude and latitudes.
So lat a and long a, that's our origin.
So that's where we start in terms of waypoints.
B is where we end up so this is our destination.
And then we've got C and D.
These are the waypoints now I've limited this to two waypoints.
So in total, you've got four different destinations.
But there's no reason why you can't have more, just in this app, we've got two.
So we've got a start two waypoints and a destination.
And these three variables are using f string to create strings from these variables here.
So that origin will look something like five 7.17 4.6.
Yeah, that would be the string for origin.
Okay, same with destination.
But with waypoint, you can see we're connecting with a bar, then we are using requests dot get.
So this is a get request.
And we're saving this in a results variable.
So we're making a get request to this URL.
And then we're passing for a parameter dictionary.
We pass through origin, password destination, and the waypoints.
And then lastly, the key.
So this is the Google API key that we looked at in the first section.
Okay, directions, this is just trying to find the results and saving it in a new variable.
If directions has a status of Okay, then we work through this logic here.
And then we would turn all of this so it returns origin so the origin is actually outside of the if statement there.
So it returns them regardless.
So if it's okay, we look for the roots and legs keywords in the Jason file.
We won't go through that yet.
But during this, one of the sections, I might show you what the JSON response looks like.
Then we, we stipulate a distance, a duration and a route list here.
And then we cycle through all of the legs.
And we keep adding and adding and adding the distance, the same duration.
And that's what we're passing through to return statement here, the duration here, you can see actually, that we're using format timespan to reformat the duration into something we can actually do something with.
Okay, so that is all they are all of the mixings.
We don't need to look at them in any more detail, but we will be using them in the views.
So if we go back to users in views, if I now copy all of my views.
So we've got a few views here, let me minimize them to make it a little bit easier on the eye.
Like I say, I've got some class based views.
And I've got some function based views.
These are class based views.
This is inheriting from template view, you've got sign up view is also a class based view.
And we're using form view with the AJAX mixin.
Same as sign in, sign out, that's just a function based view, and so is profile view.
So it's right mixed bag really.
And hopefully, you can understand the different logic.
We're bringing in a whole bunch of bits and pieces from Django.
So we've got render redirect, reverse, we are using the login required decorator.
So that stops people that haven't been authenticated from seeing certain things in views, import bringing in user the built in user model.
We're then using login, logout on authenticate, these are fantastic.
They does all of the heavy lifting with the authentication of users.
We're bringing in settings, settings, JSON response.
And then these are the built in generic views.
We've got form view, template view.
And lastly, because we're using login required on a class based view, we need to bring in method decorator, we're then bringing in that's the wrong name that needs to be tutorial.
We're now then bringing in the mix ins that we just built, and forms.
Okay, so let's start quickly with account view.
This is the home view that it will be.
And it's inheriting from the template view.
So this is a template class view, we need to call the template name or create template name variable and stipulate exactly where this what the where we're going to render this view.
And this is going to be in the users account that HTML, we haven't created that HTML file yet, but we will in the next video.
Then as the next segment, then what we're doing we're overriding the dispatch method using the method decorator and passing through login required.
So this by this little piece here, the three lines of code here, what that will do that will stop anyone that hasn't been authenticated from seeing this view.
And if they haven't been authenticated, because we've got this in view settings.py.
So we've got log, login redirect URL, sorry, the login URL, it will be read, the user will be redirected to this URL.
So if somebody goes to account and they're not signed in, they will be redirected to sign in when they sign in, and it works, they'll be redirected back to account.
Okay, so that's how that works.
So that's the account view.
We then got profile view, which is function based view, what we're doing, we're creating a couple of variables, we got user and user profile from request.
The form is the user profile form, and we password instance equals user profile.
These two here, I will remove and I'll add at the top of the screen, so they're kind of global.
And we'll make that capital.
So these are the default messages and results because we're Ajax refine the forms.
So this will be password, if ever, there's an error, and that will be shown on a front end.
So as we use an Ajax to submit the form, we've got f request.is.
ajax, then we do something else.
It's a get request.
And then we pass through context, a context dictionary.
So we've got form, which is a user profile form.
And then we add a couple of key words.
The first one is Google API key, and the second one is based country from settings, okay.
And then we return render the profile HTML file, and we pass through the context dictionary.
That's how you pass the context in a function based view, slightly different in a class based view, but I'll come on to that in a second.
But if it is Ajax, then the form is user profile form, and the data equals the post data from the request.
And the instance is user profile.
If the form is valid, you save the form.
And remember, when I said we were going to add when we add a profile, we then toggle the Hasbro profile field to true.
So that's what we're doing there.
So once we've added the address and longitude latitude, we then save has profile is true, and we save the object again, we pass through Success, the message is your profile has been updated.
If elsif is not valid, we call the form error function that we created a moment ago.
Then we create a data dictionary result equals result and message keyword is message, we pass it through back to the front end as a JSON response, passing through the data whistlestop tour of the profile view, but that that is essentially how we are handled in the setting up of a profile against an account.
Then we've got a sign up view.
Look, we've got Ajax mixing, let me just bring this across a little bit, but the AJAX mixin.
And we've also got the form view.
So as a form view, you need to say what the template is that we need to render to, which is a sign up HTML.
The form class is the user form that we built a moment ago, and a success URL can just be a slash, we are using Ajax to submit the form.
And depending on the response we get from the back end, we will then redirect or not.
So we won't be using the success URL, actually, but you do need one because we're using form view.
Again, we don't need that I've already got that at the top of the screen, then what we've got is recapture.
So remember, I said we were looking at we password context and function based view like this.
Yeah, as a dictionary, in a class based view, you need to call the get context data method.
And then once you've called that, you then can add a keyword to context and return context.
So we're adding recapture psyching to context, and that is the key in settings.
And then we overwrite the form valid, the form valid method in the AJAX mixin.
And we do that because we need some new logic here, because we're dealing with recapture.
So we, we call this if self dot request is Ajax.
So if this is an AJAX call, then what we do is we get the token from the clean data from the form.
So this is the hidden input that we had in the form, then we call the recapture validation function that we created in mixins.
And we pass through that token, okay.
So depending on the response, if it is a success, then we sign that user up.
Okay, so we save the form, remember is, the form has the user creation form, which does all the heavy lifting, like I say, so we just need to save the form and it creates that user and user profile with a signal, we save the email.
So we save the username to the email field, because we use an email as a username, and we save the profile the object, then, we've used a profile, we save the catcher score to the user profile capture score field, and then we save the user profile.
So that's what we do.
Lastly, we call login.
Okay, so we've logged in, you pass the request, we pass through the object, which is the user building user model.
And then this isn't necessary.
If you're using something like all off where you've got multiple backends, then you need to stipulate what back end you're using.
But you can have that in there anyway, it doesn't really matter.
The result is success.
And the messages, thank you for signing up, we create a data dictionary and pass it through a JSON response.
Okay, so that is the sign up view.
Sign in view, again, Ajax form view, form view, again, we do all of this logic, like we did above, it's just a slightly different because the templates are slightly different.
We haven't we don't need to pass any context through.
But we do need to overwrite the form valid.
So again, very similar to above, just we've got the username and a password.
And what we need to do is call user equals authenticate.
And then we authenticate that user, if user is not none, we log them in.
And if not, we then call a form error.
So we don't necessarily need this because we are using the authentication form.
But because we're also calling the form area, I've just left that in there, it's probably surplus to requirements to be fair, but that is the sign in view.
And last, we got sign up view, which is a function based view.
And all it's doing is logging out and put, and we pass through your request.
And then once it's logged out, you redirect to the sign in page.
They are our views.
I am trying to flow through these, but be as detailed as I can.
So you actually understand the logic of what I've done here.
Like I say, I've just identified in the sign of view that it doesn't necessarily need to look like that you could technically technically, you could just use the AJAX form mixin and it will save the form.
But one of the main reasons is that we can have this success message because the the mix ins if you look on the mixin here, there is no message is very, very basic.
Okay, next URLs.
At the minute we've got bugger all in there, but what we need to do is copy And paste all of this.
So we're importing the views that we just created, the app name is users and in the Euro patterns, remember, account is home.
So it is a class based view.
So you need to call the as view method.
So as views dot account, account view.as view, you don't need to do that for profile, because this is a function based view.
But normally, and I don't know why I've done that, but we'll go profile underscore view, normally, on a function based view, I do this and I think that is the normal syntax.
So we'll go back into view, which means that else it won't like it.
So go back into URLs, and I'll save that.
So the profile views that profile view don't need to call as view because it is a function based view and the name is profile, got a sign up, sign in and sign out.
These are two, both class based and this is function based.
So that's the syntax that you need.
So if it's a class based view, you call the AZ view, this is a function based view, you don't need to, and they are our URLs.
And we're already pulling from these URLs in the URL comp, with this line here.
I've just noticed that I've forgotten something fundamental.
So we need a signals py file.
So New File, Save as this will be signals dot p y.
And what we need in here is all of this.
So we're important posts, save from signals, they use up model, we need to receive a decorator.
And we also need the user profile that we've created in models.
So the receiver decorator needs post save and the sender to do anything.
So the sender is user in this case.
So what we're listening for is a signal from the user model.
And the function is create profile, we pass through the sender, which is user, the instance of the user created and keyword arguments, if created.
So if user is created, we then create a user profile.
And the user because it's a one to one field equals instance, okay, that's what we put in signals.
But to make sure that actually fires up when we fire the local server up, we need to go into apps.
And deaf, ready parser itself.
And we import users dot signals.
And that's all we need to do.
So this, these two lines of code will be responsible for firing up this signal.
And now we need to focus on the main app.
So if I go into here, and look at the URLs we do about face, we do the URLs first.
So main is just responsible for two URLs, one of them is root, this is where you will be adding the different addresses for your directions.
And when you complete the fourth direction, it then picks up all four redirects, you redirect you to this URL, which is map.
So then we'll go to View.
Okay, so we're just looking at render, redirect and reverse, we're importing settings.
And that is wrong.
There we go.
And we just need directions.
Remember, that makes them we created earlier? Well, that is what we're bringing in here.
And then we've got a function based view, both of them are function based views.
So def route, and we create a context dictionary here and we pass that through to the root HTML file.
Very, very basic view is not doing too much.
So then, the last view that we're going to look at today is map this is where we have our map and route directions rendered.
So this is the fun bit.
So, we will be passing through a whole bunch of parameters.
So if you remember in our mixing, if you remembered on mixing, we've got this the redirect params that will be responsible for creating a parameter string that will be passed through to the main view and it will contain all of the so it will contain keywords such as lat, a long a lat, B Long Bay and so on and so forth.
We know that that am long a or both that Origin The starting point, B is the destination and C and D are the waypoints okay? We know that because that's how we created up directions, the function is also in mixing.
So we say that if there is a lat, a that B that's Seeing that D, then do this call of directions, okay, else.
So if if somebody tries to visit maps without those parameter strings, it will just redirect them to main route.
So go back to the route and say Do it again.
Okay, but if there is a lot A, B, C, and D, it will try to call directions from the mixin.
And it just passes through the A, B, you know, and so on and so forth.
And that's what we built into mix ins, if you remember, there we go.
So these are the keyword arguments.
So this is what we're passing through from the view, like a lot, a lot, B, B, C, C, D, D, okay.
And that is the F, that is the L.
So this will redirect.
But if it doesn't redirect, then it'll create a context dictionary.
There's a lot going on here, we're passing through the API key, base count country, this is all required for the API call that we're going to make.
Plus, it passes through the origin, the destination and directions, because we need that to render onto the HTML file, which is mapped dot htm, l.
So they are the all of the views, they are the URLs, the models, and so on and so forth.
That just leaves us with creating a templates directory.
So we haven't got anything in there.
There's a couple of ways of doing this.
Now, if you're creating reusable apps, ie those sort of apps that you can, you can upload onto p IP is that other people can actually install them, then it's it's probably best for you to have templates in the actual app.
So it's all contained in one.
But as we're not doing that, you don't need to do that.
So all you need to do is add a directory in here in the main directory, which be new folder.
We'll call this templates.
And all we'll need is a new directory in there for users.
And we'll need one in there for Maine.
So when we're referencing Maine slash map dot html, we'll be looking for a file in here, if I save this as map dot html, this view will be looking in main format HTML.
So we'll be looking for that.
That's how that works.
The only thing is, this project isn't geared up to look for templates in that directory, we need to go into settings.py and tell it where to look.
You do that by going to templates you're going to does, and all you need to do because it's in the main directory, you need to put templates.
And that is it.
Okay, I hope that that was a good balance of firing through everything.
So you can get through it nice and quickly, without skipping over kind of some fundamental stuff.
We've got covered a lot of ground, we have started a new user app, we've built a model, some model forms and views from URLs, you know, we've reconfigured settings, the URL comp, we've configured templates, we've covered a lot of ground, but that is in terms of the back end in terms of Django, that's this app is complete.
It won't work.
That's what we look at in the next section.
But one thing actually, I've just noticed also is that in our settings.py file, we're referencing a directory that's not there for static.
Now, that's an easy fix.
New Folder, and we'll just call this static.
That is our static directory.
And that is what this is referring to.
That is the end of this section.
I hope you've enjoyed it.
And I look forward to going through the next few bits and pieces.
Everyone, it's probably from decoded here, and in this section we'll be following on from where we left off in the last one where we fleshed out the back end of this Django project.
In this section, we will be playing with the front end.
So this is the fun bit of the project actually, because this is where all kinds of strings gets strung together.
So without further ado, let's jump straight into it.
If you look on the screen here, I'm open on the Django Doc's for template tags.
Now I have created a video on my decoding channel that does a deep dive on tag template tags and filters.
So if you want to understand what they are then by all means, have a look at that rather than me going through this page.
But we'll be working with a lot of template tags today.
So have a read and have a watch and then come back I guess.
But this go jump straight into the Sublime Text.
This is the project where we left off.
On the last section, you can see here that we created a static directory, and a templates directory.
This is what was the last couple of two or three minutes of the last section.
This is what we did.
And we've got main other users in there.
So what we'll do now is we will create the first HTML file, and that needs to be in templates as a base.
So new file, and we will call this Save as base dot html.
Okay, and I'm not going to write this from scratch, because it will take forever, I didn't design this app to be kind of basic, you know, it looks pretty actually works, you could done it resizes is responsive.
So there's a lot going on.
So what I'll do, I will quite simply copy, copy and paste it all across.
And I'll walk you through what I'm doing.
Let's move this over here a little bit.
So first and foremost, there's a template tag here, which says load static.
This is a template tag that allows us to access our static files.
Now static files, as configured in settings dot P, while p y are all going to be in this directory here, as we're in development.
However, if we were in production, then you would set up static files in a slightly different way, and maybe have them served up to the project via an s3 bucket or something like that, or digitalocean spaces.
So this load static template tag allows us to access files in static directory, we've got some basic HTML here, I'm not going to do a deep dive at all.
But we've got this is the main that all these links here, these are my fonts.
So we use Korea prymatt decoding, we then got a stylesheet that we're referencing main dot CSS, we'll be playing around with that in a second.
So this bit here is calling a CDN, essentially.
And this is for toaster.
So we'll be using toaster alerts to display messages from the back end.
So if you remember, in views, we've got this message, defaults to there was an error.
And result is error.
Well, that's going to show a red toaster message.
If you don't know what it is, if I go back into my browser, I've got toaster examples here.
So this is a success.
But we can have a bottom right, which I believe have gotten this project, show toast There you go.
And it can you can have whatever you like in there, you can test show toast, there you go test.
Okay, so that's what we use in this project.
Go back into the project here go back in a base.
So that's the CSS that's required for toaster and we always stick that in the head, you've then got block, extend head, so we use a block template tag.
Okay, so this allows us to extend head scripts that under the law, so I've got some notes in here as well.
So we've then got nav, we're using an include template tag, we haven't even created this yet.
So I'll do that now quickly.
So new folder, and this needs to be called partials.
And in partials we need a new file called nav HTML.
Okay, so that will now be picking up from this one here.
Go back to the base.
And so this include template tag, rather than having all of the code is going to be in nav HTML, use the include the kind of interjects that HTML element into it, then we've got this div.
So don't worry about these too much.
The classes, I will be creating some CSS, because I've named these specifically in certain ways so that they get rendered nicely and looks great on the front end.
If you remember when we looked through the the demo of the app, it looks pretty good, right? So we've then got include partials logo, hate logo, HTML.
So let's create that.
I can't talk today, let's create that quickly.
More, save that as logo dot html.
I'll bring across that code in a second.
Anyway, save, and then we've got a block.
So these blocks allow us to extend certain parts of this base.
In other templates, it will make more sense in a second.
And it's called content.
So we've got block, extent head block content, and we've got another one here, extend footer.
So these are our footer scripts.
So first and foremost, we're using something called jQuery.
It's all done asynchronously.
So that's why we need jQuery.
But you can get this code from code.jquery.com.
And you get the most recent version.
And then lastly, we're referencing main dot j s.
So there's two files in static that we do need.
Save as this will be main dot CSS.
So even if we were to not pay anything, those files, we're not going to come across any errors.
And then we close up the body in HTML.
So that is base HTML, we don't need to do anything else in that file, all we now need to do is create the documents that will be extending these blocks.
Okay, so the first one we'll look at is the index or in this case, it will be account, which is in users.
So create a new file.
As we save, as we'll call this count, dot html, in fact, was Save As we need another one in here called profile, save as another one in here called sign in as underscore, save as another one called sign out.
And whilst I'm at it, I will also do the map.
So templates kind of main overall to get map in there and will route safe, good, that may close some of these down got far too much going on up here.
As a real bad habit I have.
There we go.
So then what we'll do, we'll look at account.
Okay, so this is our homepage.
So I will copy.
And I'll paste this across.
So extends the base dot html.
So it's extending this, okay, as another template tag that Django has load static.
Okay, so we've now access static again, we're not adding it that doesn't necessarily need to be there, but it's not hurting anyone.
So we'll add that if I wanted to add a script in there, for instance.
Yeah, so with ADD script, you could then add something in there.
But we're not so we won't.
But this is a block content.
So this is the content that will be injected, if you like, into this section here.
Okay, so block content.
So block content, block content, okay.
So we just save this.
So got h3 tag, as you know, is a Django Google API course.
And this is the user account.
And then we've got a div, which is container.
So we'll be referencing these classes in the CSS, but I'm not going to dwell too much on CSS.
So we'll quickly do that in a second.
Then we've got h4 tags, so user account details, and then we've got a table, okay.
And in that table, we've got a table head, it's got a head, and then blank, sorry, a field and then a blank field.
So there's no header there at all.
Now we've got a table body, and then for each row, so we've got user name, request dot user, dot username.
So Django uses something called context processes that always pass through request to HTML, so you can always access request.
Therefore, you can always access request dot user.
And fields such as user dot user name, you can access things like in our case will be request dot user dot user profile dot address, things like that make queries such as if request.user.is authenticated.
So it's really really handy that context processor is used more than anything else.
The next row, we've got name.
And then we've got so we use a filter.
So this is a template filter, request dot user dot first name, title.
So this will put a capital letter at the front of the name and then space last name.
So first name, last name.
And then we're doing an if statement here.
So an if else.
So if request dot user dot user profile dot has profile.
So if they've added an address, display this, which is a table row, details, our address, then I'll show address, town county postcode else.
So if they haven't, so if they're just newly signed up, then it'll show us a profile, and it will have an a tag with a href and a link.
So we use an a URL template tag to user's profile.
So it would just be a hyperlink where they can click it, and it will take it to the profile, so they can then select that address.
So this is why I've got that has profile in as a field on the user profile model.
That's all what's going on in account.
Not much else.
So let's build out the profile.
Paste and save as bit more going on in this Gannett extends base called load static.
Now we've got the block content.
So again, this is the block, then we've got extend footer.
So if we remember in base, we've got this extend extend footer here.
That means that anything above this I can reference.
So I can definitively know that any Ajax I'm writing in main dot j.
s, it will work because jQuery is loaded first, okay.
And a block extends footer.
This is all loaded before my day.
So I can actually reference any variables that are stated in the extend footer block.
So in profile, we've got extend footer.
And then we've got a script.
And we're creating two variables.
one variable is Google API key.
If you remember, we're passing this through.
Let me remind you profile view.
in context, we're passing Google API key and base country through to the context.
That's how we were accessing it here.
So we can access this in the main j.
We're calling it Google API key.
And we are, and we're using the safe filter.
So that will just create a string of that API key.
Same goes for base country, the next script is a file called Google Places, dot j.
We haven't got that yet.
So we will create that now.
So it's Google Places.
Save as API dot j.
Go back into profile.
So that's now referencing a file that is there that will work.
Go into the containers, this is the main main bits and pieces.
So we've got an if statement here with an else so if the request dot user dot user profile has profile, show all of this else, add address, okay? And if case so we have got, and if I okay, just trying to figure out what I've done here.
So this is input Google address, right? Okay.
So this here is that the main input for the Google Places API.
So this input here is the input where the user starts typing an address.
And Google API predicts what they're trying to type.
And then it returns the address, they select it, when they select it, it then populates all of these inputs here, which I'll show you what I'm doing in a second, let me just cover this off first.
So if they have a profile, it will display the profile.
Okay, so it will display the address, and then it will have a change address.
And then it will have or else it will have add an address.
So if it changes the address, you can then change the address to the new one, you'll type away in any address you select, it will change.
If not, you just added an address.
So this is the main input you see here we've got name Google address, ID is ID Google address, we will be referencing them in the Google a Places API, just for reference, then we got a form.
And then that is the end of that, really.
So we'll look at this form.
So the idea is profile form, we will be creating an AJAX call using jQuery on that.
So that is the name we'll be referencing profile form.
The method is post and the action is for slash profile.
So that's essentially the URL we will be firing the AJAX call to, which is, if we look in URLs is here.
So as the profile is the name, and that is assigned to views dot profile view.
Oh, okay, so let's look at the form.
So as it's a form, we need to use another template tag and this will add a hidden input with CSRF token.
So CSRF token means cross site request forgery token and it's a token as applied to a forms when you submit the form.
It knows That is actually you doing it and no toe rag doing it from somewhere else.
And what we're then doing is we're creating these labels.
So address is actually now these are hidden, right? So that class is hidden L.
And it's hidden.
So the label itself is hidden, class hidden L, and is hidden.
And form dot address, if you remember, that is a hidden input.
So we're gonna forms hidden input form, sorry, hidden input.
So all of these are hidden.
So they will be rendered as hidden inputs in here, as is the label.
So label and input hidden, then you got town, county, postcode, country, longitude, latitude, none of these will be displayed until the user selects the address.
So you can't submit the form until an address has been selected.
And we add an ID to this Profile button, because we referenced that and we programmatically click it when the address has been selected.
Okay, so that's the profile HTML.
Next, let's look at sign in a gay and let me get my notes.
And sign in.
Paste extends base, same as we load static, always the same, then we've got the block content.
Okay, not much else going on in this.
But we've got an h3 tag, and then we've got to contain here.
So this is, again, is a form.
Yeah, so against CSRF CSRF token, the ID sign in form, post sign in.
Okay, so I'm having the ID, the method and the action, always in the form as attributes.
Label again, right, so we're creating a label.
The difference is this isn't hidden in the form dot username, because we use in a form view, you access the form from the form object, so it's form dot username, and as the the input.
So if you look at forms, username, password, fields, username, password, that's how we reference the number in sign in a case, that's why we got form dot username, form dot password, then we've got label.
So this is show password.
So if you remember in the forms, we have got a class.
Let me show you.
So what I'm doing in signing is on click, so this is a little checkbox, right.
So the CSS will make it look pretty, but essentially, is a checkbox.
So if it's unchecked, it will be a password input.
But when they click it, it becomes checked for starters.
And it calls a function called show password or show p word.
So you can actually see the password, okay, which is quite standard on on websites.
And then a button is submit and sign in.
Okay, nice and easy.
Next one, sign out.
Sorry, sign up.
Now, that should be sign up, we know.
There we go.
So we will copy and we will paste.
Like we more going on in this one.
So extending base HTML, and we're loading static, free standard stuff.
And this one, we are extending the head, we'll come back to that in a second.
We've got block tank, we've got a form.
And we're extending the footer.
So if you remember in the sign up view, we're playing around with the contacts using the get context data method.
And we pass in three recapture site key, okay, which is the recapture public key.
The form is pretty standard, similar to what we just done CSRF token.
Then we've got the first name, last name, username, password, one password, two differences.
We've got token in this one.
So the token if you remember in the forms we added as a hidden input, and that is how we're going to be handling the reCAPTCHA token.
Okay, so that's a hidden input, you won't see that when it's rendered.
Then we've got this little checkbox box to show the password again and a sign up Submit button.
Okay, so that is the form.
And what we've got at the top here is a script.
So this is the source is the url https google.com reCAPTCHA.
And we're passing through the, our reCAPTCHA.
So that's how it knows that it's us making the call to recapture.
Because the psyche that we set up when we set up recapture in the first section, we're linking it to that API key.
So essentially, this script, being in that extend head is the equivalent of it being in well, it'll be there but without the head.
So imagine, imagine that Okay, so that's what we're doing by adding that to the extent head.
That is the signup page.
So now let's look at the main map.
Actually, let's look at the parcels quickly.
Okay, so this is the logo.
So it's just an a tag, essentially.
And if I save that, so if you click on the logo take you to a user's account, which is the homepage, and it's referencing, I think that's the first time you've seen this in this tutorial, load static.
So this is how you reference the static.
When you load static, you can then use the static template tag.
If you didn't load it, it wouldn't work.
And we're looking in branding.
So in static, new folder, branding, and is trying to find a GIF, which is a dead logo GIF, we'll add that in a second, which won't be a problem at all.
And then we will add the Nef got a lot of if statements in this.
nothing too fancy To be fair, it's got an if statement if else.
So if the request dot user is authenticated, so if they're signed in, they will see this now.
If they're not, they will see this nav, okay.
So this look at if so when you first enter the site, if you're not signed in, you'll add if signing in path.
So if the URL is sign in, then this will sign in will be active.
So on the side now there'll be glowing up purple, if not, it will be blank.
If it's sign up, it will be glowing up purple, if not blank, that's what these if statements are doing is just basically showing whether or not is active or not.
If they are authenticated, and the request path equals equals slash, which is home.
Again, active if not Same goes for profile, route map.
Okay, so it just shows different, different navigations.
To be fair, let's close that.
Let's close that.
Let's close sign up, sign in profile and account or keep base open.
We'll close that.
And now we will do map.
It's going to map or paste this a lot more going on in this.
Okay, so map extends the base HTML load static.
In this one.
Again, we're passing through recapture.
So recapture site key, okay.
And then to be fair, we probably don't need to, that's probably a hangover, but I leave it in there.
Because we're not making a reCAPTCHA call in map.
We're only making it in, sign up.
Okay, so we've then got h3 tag, and we've got a container.
So what's going on here? We've got I'm going, do you know what? Let's do root first.
Nasty read first.
Okay, this is right.
So route is the the URL where we add the longitude and latitude for the origin, the waypoints and the destination.
And map is what's rendered says the last point in time, actually, so let me look at real quickly.
So I've just pasted that all in that extends base load static.
And then again, we've got recapture.
We don't need that.
I'm sure I can remove that.
But I'm not going to because I haven't tested it.
And I know that it works in in the other project.
But we're not technically making a recapture call.
So I'm, you know what I'm saying that doesn't need to be.
Okay, then we've got the h3 tag, and then we've got the inputs.
So this is the same as account, no profile.
So in profile, if you remember, we have this input here.
And we call it ID Google address difference here in roots is that we've got four.
So if you look here, I've got ID Google address, dash a, dash B.
So remember, start and end.
Don't ask me why I didn't go ABCD.
It seemed logical at the time but looking back, I probably should, should have gone a B, C and D instead of going to a and b, that is point A, B is the destination and a waypoint system.
In day, a guess, because you can do more waypoints.
So it'd be C, D, E, F, G that way, but hey, the logic was there when I was building it.
So these are the inputs.
So as you type in here, it will predict the address as you type in C, it will predict the address, and so on and so forth.
And when you select each of them, it then adds the geo coordinates the longitude and latitude to each of these hidden inputs here.
So this class is geo ideas lat a long a, okay, and then it adds a value.
Yeah, we didn't need that.
reCAPTCHA at the top of the screen, because even passing through the reCAPTCHA key, so I can remove that from map as well.
Let's, let's remove that.
There's no point in it, bns.
So save back to root.
So this is the extend footer.
So we've got a script here, a couple of variables, Google API key and base country.
And also we are then referencing the Google Places, waypoints j s, because in this we have to.
So that's add another one.
And save us.
And this was Google waypoints API dot j, s, waypoints API.
Let's have a look was probably wrong.
Google Places, waypoints, points.
And then if we delete that, there we have it, we've now got that file.
So that's referencing a file that is actually there.
Okay, so now we'll look at the final HTML document, which is map dot html.
So if we go in here, I did paste this a moment ago.
Anyway, you can see that we've got quite a lot going on.
This is where we render the map from Google.
So let's look at this look at the footer first.
So we pass in through if you look at the map, view, in the context, we're passing through all of this, okay, so we're passing through the key, the base country lat long the data that the data in maps, we are getting all of those.
And then you got we're creating variables a lot, a lot longer a an NBC D, origin, destination and directions, we're going to need those in the Google Places API, and Google Places, waypoints.
So New File, Save as Google Maps dot j s.
Okay, so we'll be needing all of that in Google Maps, okay.
Then got another h3 tag.
And we'll focus on this.
First of all, we look at the table in the container.
So this is the map container.
This is the map route.
Then if we look at things insane, I've got another table.
So we've got to start the destination, a duration and the distance, that's kind of the header of the table.
And we're pulling from directions, origin, directions, destination.
So that is what comes through when we call.
If you remember, we've got directions here.
So we're passing directions through to the context.
And that is essentially a dictionary.
So we're referencing keywords in that dictionary directions, such as origin, destination, duration, and distance.
And that's what's being rendered here.
And then we've got on click directions toggle.
So this is how you view the directions, it doesn't show the directions in tissue until you toggle it.
Okay, so that's just a little little link that we've got there.
And then we've got another table.
So we've got table head directions, distance duration, and this is where it renders the whole route.
So for each leg, in directions dot route, we do a for loop and a counter.
And then we do this for loop here.
With dist duration text, we're creating those variables that we can reference down here.
And they are in leg dot steps within a foot we're doing a for loop in leg dot steps, create three variables, distance, that duration is there and text say Is that because that is raw HTML that comes through from Google.
And that's why we need save, because it will actually render that HTML properly in the website.
And that's it.
That is maps.
Okay, the next thing we need to do there, all our HTML is complete, we now need to add some CSS.
Which would do, I am not going to waste your time on CSS, this app tutorial was all about showing you Google API's and Django.
CSS is not an afterthought.
It's very, very important.
It makes it look fantastic.
But you know, we could spend an hour going through CSS, which isn't necessarily important.
But you can see, I'm referencing body.
I'm saying that the font family for this particular file is Korea prime, which is correct.
The map root element.
So this is what we just looked at here.
Where is it? So map route, so we're referencing different elements in each of the HTML files.
So we've got map container.
So I've probably got one for if I search.
There we go body HTML map container height 100%.
After they need to search flowers right at the top, but then got logo got a side now.
So this tells you this shows you what the sign level look like, then we've got some some media screen.
So it depends on how big the screen is, is how it gets rendered.
These are how the inputs look.
So a text input an email, password input, we've got select text area, this is how it's rendered this how it looks, we've got width, 100%, padding, 12, so on and so forth.
Okay, so we don't need to waste our time on this, which so we won't.
So if I go into main, paste this, right at the bottom here, we've got code straight from Django.
So let's go right at the top of the file, there's open up a little bit, like directions toggle, if you remember, in maps, I saw that directions toggle somewhere Hey, guy, so we've got a little link here.
And it says, click here to open up the route basically.
So you can see the route for the map.
And it's unclick, you called direction toggle.
And all it does is it opens up a removes the hidden attribute and adds a new element.
But that is what is doing.
And it's fading in the directions table, else you fade out.
So you either display it, or you hide it, one or the other.
Show it up.
This is for toaster.
So we call Shola.
Every time we make an AJAX call.
And it depends on if it's a success.
Or if there's a redirect, for instance, we pass through all of these keywords, all of these keywords here.
If there's a redirect URL, and we call this toaster, house, we call this toaster.
So what what is doing is picking up the title.
So in that case, it could be success, that message could be thanks for signing in.
And it's creating a toaster.
So if you look at the examples, again, is creating a toaster based on all of this.
Okay? So that's the function called show that show password.
Okay? This is what's being called when you click on me open up sign up.
is they go so show p word.
And what it's doing is if the type is password, change it to text, if not change back to password, just a little toggle.
Okay, we create a variable called temp button text.
So this is the text that's on a submit button.
So it could be sign up sign in.
So it kind of stores or this will be used to store what a button is currently named.
And then you've got a custom form submit post.
So when we submit a form, what it does, it disables the button, it adds a spinner, and it saves the current text to this element.
And then when it's complete when the form is submitted, and everything's gone, well, then we then call this so as custom form, submit response.
And what it does, it removes the attribute disabled and it adds the text, which used to be so the idea is when you submit a form It adds a spinner saying loading, and then when the form submit in, it goes back to sign up.
That's all it's doing.
And we just call custom form submit post and custom form submit response when we call an Ajax.
And then we've got form controls.
So we use strict, but this is variable form controls and is equals function.
And underneath here is when we initiate the form controls.
So it's a jQuery document ready.
So when for when the HTML has been rendered, then we call the format controls, and we initiate them.
So everything within here will win work.
So format controls, we've got a few forms.
First one is user sign up, we've got sign in user profile, and we return and we in initiate and function, we initiate these forms.
So each of them certainly work.
So we'll focus on one of them.
So these we've got one of these for each of the forms that we've created.
So forms, so we're looking at user is the user form, which is the signup form, right? Yeah.
And we call that in, so we're looking sign up, we'll look at the form.
So sign up form.
So that's what we're referencing.
Now, this is what we're trying to submit from the front end, this is us submitting a form from the front end, processing it in the back end, and, and then changing the page as necessary.
We're not reloading, which is an AJAX call.
So this is the user signup form, the form, so we're creating a variable form, let me make this a little bit easier for you to see.
here as well.
So we create a variable form.
So that form is we're using Ajax function.
So your little dollar sign, Id signup form.
So the form is the signup form that is in the signup, HTML, this was one here.
Then we've got form dot submit function.
So this is when we submit the form, this is what we do, we prevent default.
So if we click Submit on HTML, submit on an HTML form, it would just do its default function, which is to submit the form to the back end by adding event dot prevent default, it stops that from occurring.
So it kind of completely stops that from happening.
And then it goes through this piece of code here.
Okay, so we've got custom form, submit post, we're calling this, remember, we added a little loader to the button.
And then we've got google recaptcha.
So we have already loaded that in this particular HTML document as this script here.
So we can now access g recapture.
So g recapture dot ready function.
So then what we do is G recapture dot execute.
So we pass through the reCAPTCHA psyche that is passed through at the bottom of this page, okay? The action is slash, because this is the homepage, right? So this is the index.
So dot then function.
So this is the token, this is the token that we get from G recapture the google recaptcha.
So document dot get element by ID, ID token dot value.
So this is the value of the token equals token.
So that hidden element now has a value of the token, and then we submit that to the back end, so var form data equals form, which is here serialize.
We call it a serialized function that, and then we call an, we make an AJAX call.
So the URL is the form attribute action.
Over the form attribute is a sign up.
Okay? main, then our wet sorry, methods.
So the form attribute method, we've then got post.
So this is a post call.
post request, sorry.
And then data, we're passing through the serialized form data.
We've got a success method and an error method.
So if anything goes wrong, right, we call the custom response.
So form submit response.
So the button on the form will go back to normal, then we'll show an alert, which be error, there was an error, please try again.
And then we do a console log that will only display if default, sorry, debug is true.
Okay, if it's false, it won't show anything.
But this will show an error if there is a problem.
However, if it's a success, can we call custom forms and met if the result equals success, because we're, if you remember, in the logic in the view, where we're overriding the form valid function, and if we show sign up view, so it's a success.
If recapture works, then respond with success.
If it doesn't, then we will call.
So it has a form invalid, we'll call a form error method in the mixing.
So if it's a success, we redirect to homepage.
If not, we redirect false.
We basically don't do anything.
So then we what we do is we call a show alert, you can't really see that, can you, we show alert, and we pass through the result of the call the message, and then the result to lower case.
And then with that, we pass through the redirect, because we are redirecting to the homepage.
This is how we're processing the form on the front end, we're doing the same.
So the reason I went through that and quite a lot of details, because we're using recapture, whereas these other forms, were not a case.
So there's no gv capture at all.
It's just basic, we're getting the form we're creating form day, it will make an AJAX call with the attributes, action method and form data.
We have got console log Jason, we don't necessarily need that.
That's for testing.
So this is the sign in function, the sign in form submission, then we've got user profile.
Okay, so this will be called when we click programmatically the submit button on the form in route.
Sorry, sorry, it's in profile, my apologies.
So it's the foreman profile with a profile form.
If you look, the button is disabled.
If you can't, you can't actually click the submit button.
So what we do is we actually programmatically click that Submit button when we get the response from Google.
Where is it the in static from one of these, probably Google Places API.
So when we get the result back from Google, we will then remove the disabled attribute from the Form button.
And then we will click the button programmatically, like I say, so it's there's no different, nothing fancy going on here.
They're all very, very similar.
But they're the three forms and they are in the main js.
So let's save that.
So let me open that up a little bit.
Okay, so right at the top of the page here, we call this so is it get script and we call maps dot Google API's comm we pass through the Google API key.
And then at the end of that we plus an S, and libraries equals places.
So this is the call that you need to make to have access to everything we need in Google Maps.
And this is what's going to be used to render the map in map dot html.
So this will be the map with the route across the waypoints.
Okay? So when done, so once you've got that script done, and does this function here, so is Google dot maps dot event, add Dom listener, window load, and then you initiate the map.
Okay, so this is just a standard get script call for Google API's, then gone in its map function.
So we have a variable of direction service and directions display.
And then a very variable of map.
So we make a new Google Maps.
And we're looking for map route.
So this is the element that I showed you in the map HTML.
So it's actually looking for this, this is where the map will be rendered.
Zoom is seven.
I can't even remember what that means.
And then we center the map against the latitude and longitude.
So that is the start point.
So that is the center of the map.
And then directions display, you set map, and you set the variable map.
And then you calculate and display route.
So this is the direction service and directions display that we'll be referencing in this function down here called calculate display route.
You got some constants, so waypoints This is the C and D.
Okay, stop over true.
So this is how we're creating waypoints.
And then we calculate the route using this function here.
So we pass through direction, service and direction to display.
Okay, and that's what we call in here actually.
So when we calculate display route, this, these are the two bits we're calling, which are here.
They knew straight from Google Maps direction service.
So we're pulling them through in here, direction, service dot route.
Origin, is origin.
And they'll pass in through the destination and waypoints these are the variables that we pass through, if you remember to here, okay, so origin destination and the waypoints the constants here.
Okay? That's what Google requires to render this map.
So optimize waypoints equals true.
Travel mode is driving.
And then we've got function response status.
So if the status is okay, so if it works, then directions display set directions response else, fire off an alert.
So that's how that works.
So we need to look at Google Places API.
we'll paste that in there.
Let's open it up a wee little smidge.
Again, we're doing another get script, same thing, no difference.
The only difference is rather than in it map we're using in it or a complete, which is just a different service.
Okay, so we let autocomplete so we have that here.
And then we have an in it autocomplete function.
So autocomplete equals, so we do a new Google dot maps dot places autocomplete.
And then we're looking for a, an element in the HTML, which is ID Google address, if we look at profile is here, Id Google address.
So we're looking for that element.
types, his address and component restrictions.
So the country this is where we pass through the base country.
So this is settings dot bass country, and this is currently set to UK, but if you set it, send it in settings dot p y to a different country, then it should technically work.
So we have autocomplete, add listener change places, so every time you change the address in the input, it will autocomplete.
Okay, so on place changed.
So if you click there different address, then it will run through this piece of logic here.
Okay, so the autocomplete This is as you're typing, it will change and predict the addresses.
But if you click the address, it will run through this code.
So you've got a place so it's a complete get the place geocoder, you're doing some geocoding there.
This is why we enabled that API, the address.
So again, we're getting the value from the inputs that we just selected.
And then we've got geo coder dot geo code, pass through the address.
And then if the status is okay, so if the address is fine, then we get the longitude and latitude from the response.
And we add those to the elements that have the ID of ID underscore latitude and longitude.
Okay, so those two inputs are now been populated.
And then we go through this logic to get the street address, the route the postal code and everything else.
And we add those to the corresponding elements, okay, so I won't necessarily need to go through them.
But with with doing a for loop on a response from Google, and we're pulling through the street number, that route, and saving it to the ID town, the county, the country, so on and so forth.
Then we add the address to, we add the value to the ID address, and then we unhide all of the elements.
So remember those everything with a hidden element class gets unhidden.
Lastly, we fade in.
So I do apologize.
You find all of the hidden elements and ignore the CSRF CSRF token, and then you fade them in.
That's how that works.
I do apologize.
And then what you do you get the Profile button, you remove the attribute disabled.
And then what you do is you submit the form, okay.
So we don't programmatically submit the form, we remove the disabled, and then the user can submit the form.
That's how that works.
So okay, Google Places API j.
s, that is that.
And then if we copy over the waypoints quickly, we'll just fly through that.
Happy Days, right? Again, another Git script difference being here, it's actually is exactly the same as Google Places API.
Okay, very, very, very similar.
So instead of Google Places API, s, j, s, where there is no auto fields, I've just got A, B, C, and D, because we just use them for waypoints.
So again, in autocomplete, so I won't go through the logic of adding the address in town and county to the hidden elements, if you don't need to, or getting a longitude and latitude.
But you will see here that what we're doing is, we're going through a for loop of the auto fields.
And we're getting a and we're Len looking for the ID Google address and we're appending the fields So this then becomes the, if it's a, it becomes the destination, sorry, the origin, if it's B is waypoint one, if it's C is waypoint two, and if it's D is the destination.
So this is the logic I had to put in here to use the Google API on four different autocomplete fields.
So that's the in it's autocomplete.
And then we've got on place change.
So again, it's the same as Google Places API is just I've had to adapt the logic to work through and identify the correct input element based on the field from the or a field.
Okay, so we're passing through the A, B, C, or D.
And we're looking for ID Google address, Addy.
So that's what I'm doing is no, no different, massive, no massive change to Google Places API j s, but then we're calling calc route, which is down here.
So this is the function that we're calling.
And this is what we're using to create the URL query.
So we're doing an encode you are I component, so we, what we're doing is, when we select those four waypoints, we end up creating a URL parameter, and we append it to the URL.
And then we this is actually quite key.
And then what we do is we call window dot location, assign, and then we redirect the user to the root URL, sorry, the map URL, and then we append the query.
So the query would be something like, boop boop, lat a, there'll be question I'll start with a question mark, and it will be lat, a equals 57.4.
And lasts so long, I hope this makes sense.
Wood equals four is 5.666312, whatever.
And then it will be joined with a bar.
And then you do another one and another one and another one.
So the parameter string will end up being quite cumbersome.
But it will be appended to the URL and the user is then assigned to the new URL with a parameter string.
And then in the map.
View, let's review the main, where are we main views, you can see that we're actually trying to pick up that parameter string.
So if lat a is found in request dot get dot get, then we can do something with it.
So that's what we're trying to do in waypoints.
Again, this code is going to be in GitHub so you can have a good look.
And make sure you know you're familiar with it.
But I hope that I've now gone through is deep enough so that you understand it without going too deep, but I've actually lost you.
So I will end this section here.
And in the next section, we will test the app and make sure it works perfectly.
And that will be the end of the tutorial.
So thanks for watching, and I'll see you in the next segment.
Everyone is probably from decoded here.
And in this section, which is the final section, I will be running through some debugging and just general testing of the application to make sure it works as planned.
So that's jumped straight into it.
If you look on the screen, I've got my command prompt open I got my virtual environment fired up and I'm in the correct directory.
So to the at this point, if you were to follow the tutorial on Django Doc's, you would have been making some of these commands right at the start of the project, but I haven't done them yet.
I haven't done it for a reason, actually.
So I what I like to do is get my teeth into a project and then start making the migrations rather than doing it right at the start.
It's just personal preference really.
So what we need to do is we need to make a few commands here.
So first and foremost, we need to make migrations.
So Python managed.py make migrations these will this will make some migration piwi files and a cache of the model migrations and other bits and pieces if it will work.
Help us out was a full stop I Chi so from human friendly import format timespan no model names human friendly so is that let me have a look quickly.
I have a funny feeling that we need to install is it's just called human friendly.
So let's go pip install human friendly brilliant Make migrations.
There we go, that worked, then what we'll do is we will migrate.
So if we now open up Sublime Text, you'll see that we have a few extra files in here now.
So we've got db.sq, light three.
So that's for the database.
So in users, when I've got a PI cache, and in migrations, we should have a guy, so you got initial.
So if we were to make a change to the model, and then run migrations, again, it would then essentially, we just create a new file.
And it will make it make a list of all of the changes you're making.
And all of the amendments, all of the creates and updates and things like that.
Main won't have it will have the poi cache, but migrations will be blank, because we don't have any models.
So these are the migrations we made, you'd expect it to look like this.
So we've got dependencies of the off user model, which we have, you know, that's the one to one field.
And then you've got the ID, timestamp Date field, dadda, dadda, dadda, that, okay, so that's what we're done by making migrations.
If we now run server, say Python manage.py run server, hopefully, we'll be able to see what the project looks like on our browser.
So let's go Ctrl Shift and open up an incognito screen.
Just to level it off a little bit.
And if we go, local host with Port 1000.
Wonderful, I was hoping that was like that.
So you can see here that it's gone.
Sign in question mark next.
Okay, so the accounts page has redirected us to sign in.
So we haven't got an account.
So we will sign up.
There we go.
So object has no attribute recapture public key.
So what have we done here? So if we go back into settings, rights, okay, so we'll call this public key.
And we have a look at my other project to see what I did call it.
This, so as weak, there we go.
So and that one isn't secret key, we need to call that private key.
So okay, so that will now reset the server thing that's now working.
And if we go back, this is what you see on the screen here, because we've got debug set to true.
If that was set to false, you won't be seeing it.
There we have it.
That's all our work.
And so this is the sign up page.
Okay, so let's go Bobby Stearman, username, Bobby at did coding.com password, this guy.
Password 123455, click Show password, it will show that, okay.
And the reason it's showing that it's because I'm toggling between a password field and a text field.
So that's click Sign up, you can see here, the fact that we've got this reCAPTCHA element at the bottom of the screen, which suggests that it's actually working.
So let's click Sign up.
I was too common.
So you need to have a good password.
So let's go.
can't assume that's going to be very There we go.
Thank you for signing up.
So the fact that come up with an error and it come up with a message shows that the form errors actually work in a mixin, which is fantastic.
So now that we're signed in, we're now in the accounts page, which is the homepage right? If we're not signed in, it will redirect us to the sign in page.
So the username decoding user name is Bobby Stearman.
Let's create a profile.
So this is the recap, not the recapture.
So Viper 123.
All Okay, that's not working.
Okay, that's not working inspect, console.
Failed to load resource.
The server responded with status of 404.
So Google Places dot j s cannot be found.
So static Google Places because it's not get this Google Places.
That right, is that we're referencing and let's look at the templates.
So that was a mistake on my part.
So this is all part of debugging.
So if we refresh the page that will now go because that file has been changed, the name has been changed.
So if we now go 123, this page cannot load maps correctly, do you own this website? Interesting.
Then you just keep debug this quickly.
Okay, I figured out what it was, it was because I hadn't enabled billing on the API.
And you have to do that for it to work.
So go ahead and do that on your API keys.
So if I now go, 123, there you go.
And then we'll click Buckingham Palace.
And then we'll unhide all of those hidden elements, and we'll click Update.
Your profile has been updated.
It should now There we go.
So use a profile.
If we click to that you can change the address.
So as create or update, which is great.
We then got root.
So these are the four so this is the start address, waypoint.
One, two in destination.
Let's see if this works.
So I'm going to go with Okay, I know that address.
I'm gonna go with one.
There we go.
I will do another.
Okay, one High Street Stretton.
There we go.
No, not that one.
One high streets.
Stress him, or click on that one.
And lastly, we'll go with one marketplace eally.
And now that I've completed all four waypoints.
Can you see this? So we've got map question mark, then we've got lat a, and there's got long a, that B, long B, C has created that parameter string, that's what's being used in the view.
Okay, so we go into the view in Maine.
There we go.
So it's picking up all of those from the parameter string.
So we've got start destination, duration, distance direction, that's about right.
To be fair, if you're gonna do that little route, that's exactly how far I'd expect it to be.
This is the map.
Sutton had them stratum eally.
If we click on this will this work? Happy Days, and that's the directions.
Let's just double check the sign out works.
There we go.
So site this check sign in, as well.
So as Bobby did coding.com was it Fred, Fred one, I think our use check show passwords.
You're now logged in.
Everything works to plan on over the moon.
So there we have it.
There's your Django app that works with two Google API keys, and six different Google API's, one of which is recapture.
And the others are a whole bunch of maps API's.
So we can do predictive addresses.
We can use maps, we can use waypoints.
And it looks pretty good as well.
So you can find this code on my GitHub, the GitHub repository link will be in the description.
Thank you for watching, and I will be seeing you in the next tutorial.