Python Django and Google APIs - Project Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
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.
Info
Channel: freeCodeCamp.org
Views: 109,415
Rating: undefined out of 5
Keywords:
Id: _vCT42vDfgw
Channel Id: undefined
Length: 138min 50sec (8330 seconds)
Published: Tue Aug 17 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.