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. easily. 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. And after that, we
will then go to Google Cloud, and we'll be setting up another API key that will allow us to set up by
an enable five API's places, directions, Distance Matrix, geocoding, and Maps JavaScript. 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. And submit. 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 we will set up the Google API key that will allow us to work with
places directions Distance Matrix geocoding, and Maps JavaScript, what you need to do
is visit the website cloud.google.com. 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. Click Create. 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. Close. 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. tutorial key. And save. 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. click enable these next API, so the
directions the distance, the geocoding, and the maps, JavaScript, these are
the API's that we're going to use when working out different routes and
distances between two geo points, so to longitude and latitudes. 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. Lastly,
we need to find the Maps JavaScript API, and enable that. And that will allow us to
write some JavaScript to actually make the calls themselves because we won't be making API calls
from Django, the calls themselves will be handled in JavaScript. So let's click the Maps JavaScript
API. Enable. 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.
And then we've created another API on Google Cloud and enabled Google Places Google directions Google
Distance Matrix, Google geocoding, and Google Maps JavaScript API's. 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. Thank you. Bye, bye. 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. So we will be using a Python web framework called
Django and we'll be working through how to start a new project how to create an app, how to configure
Get some settings and static files such as CSS, JavaScript and images, and also playing around
with the URL comp. 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. Okay, great. 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. CDN. Okay, they are the only changes we need to make to
Settings dot p y in regards to static files. You need these variables for it to work and serve CSS
and JavaScript files to the project to the front end, I won't do any more of a deeper dive than
that. 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. Capture. 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. Okay. 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. app name. 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. Bye. 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. In the
next section, we'll be looking at the front end which is all about HTML files, CSS, Cascading
Style Sheets, and JavaScript. 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.
Yeah. Okay. 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. Great. 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. That's great. 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. So the
JavaScript that I've got in his project uses a country code. 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. But it just means that we can change it in the settings without having
to change it in the JavaScript. 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. Okay. 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. And paste. 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. For Ajax. So this is
the form errors. function. 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.
validation. 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. And you can change
bits and pieces using JavaScript. 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. Okay. 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. Okay. 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. Okay. 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. Okay. 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. Okay. 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. Most of it will be or most of the heavy lifting in on that view will be
done using the API and the JavaScript, which we'll come on to in the next section. 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. Okay. 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. And we will all become clear, when we start writing the JavaScript
passes through all of the longitude and latitude, and so on and so forth. 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. However, because we haven't got anything, such as CSS, HTML, or JavaScript.
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.
Great. That is our static directory. And that is what this is referring to. Okay, good. 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. Thank you. And goodbye. 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 we'll
be creating HTML files, CSS, JavaScript, jQuery, Ajax, and Google API's. 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. top right. 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. body. 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. New File. 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. This is a, I believe, the most popular JavaScript library, and it allows
us to access things such as Ajax so we can make an asynchronous form submission for For instance,
we submit the form and we get the response and nothing reloads on the HTML page at all. 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. Then we've got the toaster JavaScript, which
is all this again, you can get visit this CDN JS calm and get the latest version from there,
then we've got a block for extend the footer, again, it allows us to extend this part of this
HTML into another document. And then lastly, we're referencing main dot j s. So there's
two files in static that we do need. So new file, and we'll save this as main dot j,
s, that'll be a JavaScript file was Save as again, and we'll call this main No, we weren't.
New File. Save as this will be main dot CSS. So there we have it, we've now got the main CSS
and main JavaScript, so we're referencing them in base HTML. 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. Right. 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. This is more about the API's and JavaScript. 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 it. 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. The main j s is always the last JavaScript that we load, it's just the way I
do it. 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. So this is a JavaScript 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. Okay. So we'll create a JavaScript variable. So we can access this in the
main j. s file. 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. s. We haven't got that yet. So we will create
that now. So it's Google Places. Save as API dot j. s. Great. 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. Okay. And the reason we're doing this is
because in the JavaScript in the main j s, we write a function to display these hidden
elements, when we select an address, and this is why we're doing it. 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. And then we've got a JavaScript
function that will unhide all of these elements, the button to submit is disabled. 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. Copy across. 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. That way we
can when we're making the call in the JavaScript is a lot easier to understand what's going on.
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. Class password.
Okay. 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. Now this function, I'm going to write in
the main JavaScript file, and that will essentially swap that password input to a text
input. 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. Sign up. 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. And we're creating a variable recapture site key
that we can reference in the JavaScript that we haven't written yet. Okay. 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. api.js JavaScript. So this is the JavaScript that we're pulling
straight from Google. And we're passing through the, our reCAPTCHA. psyche. 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 and that is
the JavaScript call as the script we sit in the extend head. 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. So that's the JavaScript as long as content happy days. That is the signup
page. So now let's look at the main map. Actually, let's look at the parcels quickly.
Copy partials. 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. Okay. 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. So copy. It's going to map or paste this a lot more going on in this. Save.
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. Yeah. 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. I'll be using JavaScript to add that 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 we're creating, in this case, we're creating
a string, we're always using the same filter, else, JavaScript doesn't like it. 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. And also, Google
Maps JavaScript, which we haven't created yet. 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. So we will be referenced in this ID map, right? Because Google that the Java scripts
in the Google j s files that we're just creating, they will essentially be rendering the maps and
everything else, all of the routing and stuff into this element called a map route and will
be referenced in map pre in the JavaScript. 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. Then we've
got directions, and we've got ID dir toggle, so this is JavaScript void, h ref. 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. The next thing is the main JavaScript. So if I go
into main, paste this, right at the bottom here, we've got code straight from Django. This is a
JavaScript function to get the CSRF token from a cookie to and then it passes that through with
an AJAX call, this is a way to work around to make sure that the right CSRF token is passed through
when a form is submitted. Okay, so it's very important you have that in your JavaScript file,
when you submit an Ajax. 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. So we don't need to necessarily go
through the JavaScript itself. But that is what is doing. When you click that toggle is calling
this JavaScript function. 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. So if we add a close button in the progress bar, and then tap show test, says
creating a unique toaster and that's what I'm doing in the JavaScript there. 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. Okay. So this is a JavaScript function has been called.
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. So this
is kind of a general JavaScript function that we're doing here. 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. Okay. 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. Okay. 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. Ready. 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.
Okay. 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. Okay, so that is
the signup form logic in JavaScript. 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. So we'll be submitting this form in JavaScript from
the 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. We've done the CSS, we've done the JavaScript now we now
need to focus our time on the Google Maps, Google Places and waypoints. Okay, now, what we need
to do is add the JavaScript to the Google Maps. Copy, Paste. 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. Okay. 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. Okay. 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. Okay. So that's how that works. And that is the
Google Maps JavaScript. 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. Okay. types, his address and component restrictions.
So the country this is where we pass through the base country. Okay. 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. Okay. 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. It just this is slightly different because we are using this JavaScript
for four different inputs. So had to manipulate the JavaScript slightly to work. 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. Okay. 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. Okay. 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. Thank you. Bye. 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. Okay. 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. Okay. 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. Right. 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. P word. Let's go. Password 123455, click Show
password, it will show that, okay. 12345. And the reason it's showing that it's
because I'm toggling between a password field and a text field. Okay. 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. Let's go. Fred. Fred, one. 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. This
is the Google Places, JavaScript. 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. Okay, interesting. 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. And we'll look at profile and what are we looking
for here? Google Places JavaScript. So that was a mistake on my part. Okay. 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. Wonderful. It should now There we go. Brilliant.
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. Cherry Orchard. 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. uk. 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. Okay. 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. Brilliant. 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. Sign In. 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.
It's fantastic. 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. Thank you. Bye bye.