Django and Vue CRM tutorial - Full course with Django Rest Framework

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
the project we're building is going to be a crm or a customer relation manager i'm going to implement different things for both django and vue which is the tech stack for this video series the back end will be built using django rest framework and then the front end will be separate built to its vue.js i want to show what i do when i build projects on my own so that's why i'm going to record it while i'm building it and i'm going to explain to you as good as i can what i do and why i do certain things some of the features i will add in this project will be authentication lead registration with multiple statuses and similar and leads can also be turned into real clients where i can add notes and tasks for the sales people i'm also going to implement different roles because that's something many of you subscribers has asked about so i'm going to have two different roles one for normal users and one for the managers and the main difference is that the managers will be able to add users which the normal users can't and that's mainly just to show you how you can implement roles using django rest framework as i make the project even more exciting i'm going to implement the payment gateway so i want to make it possible for teams to register and then pay a monthly recurring amount so they can have access to the web application today we are going to build a simple crm using django with jengarest framework and build the front end separately using vue anyways in this port we are going to focus on the front-end by installing view and a few other libraries we want after that we're going to set up a few simple pages etc so we can then begin with the first task which is install view and some libraries so if i just go to my terminal and go into my folder documents connor crm this is the name gunnar is spanish for win or earn which is what we want with the crm we want to win customers so the first thing installed is view and to do that i just say npm install dash g at view slash cli this will install the newest version of view okay i still don't have anything in this folder except for my to-do list so what i want to do now is to create the view project by saying view create conr crm underscore view and i want to manually select which features i want to use so just down arrows and hit enter i want payable not typescript it's not progressive web apps but i want a router i want view x and i want css preprocessors and i don't need linters for this project and then i can hit enter and i want to select three dot x here so it'll get view three and i want to use history mode and i want to use dart says and this can be put in dedicated config files and i don't need to save this for later so now the project will be created on my mac okay everything seems to be okay so i can go into the folder cd conor like that so now in the root of the folder or the view project and as i said we also need to install a few other dependencies or libraries first we can install bulma which is a css framework i love to use npm install bulma feel free to use bootstrap or something else if you want to but then you need to change the html i use a little bit next we can install bulma toast this is a little library to make it easy to show notifications to the users npm install bulma toast and then last but not least axios axios is a library you're going to use to handle ajax in other words talk to the backend most browsers support a built-in function you could use called fetch but i really like exo so i'm going to stick with it for the series as well again install axios great so now everything is installed and i can go back to my to-do list and set this task to done next now is to set up the libraries and i want to configure excels first and this is done inside the src main.js file so here i want to import excels import excels from excels like this oops excels and then i want to append it here after the router the main.js file which we are in now is where view is initialized as you can see here we create app and all of the setup is done i will come back to all of the other files later in this tutorial so don't worry if you think there's too many files you don't know what to do yet and then below here i just want to set the default url for excels so excels defaults dot base url equals http one two seven zero zero one eight thousand and this is the url for the django back-end which you will great later so now i can just save and close this file and then the next bit of configuration is bulma this is very simple because you can just import the sas file from bulma inside the approach view file so i just want to remove this default styling that comes from vue and i say at import dot slash node modules slash bulma and that's it so then i can go back to the to-do list and set the next source to done as well i also want to create a component for the menu this is to make things as clean as possible for the app.view file so inside this components folder and component is reusable pieces of code so in here i want to create a new folder called layout and in there a new folder called nav bar dot view have capital n like that because that's how you do name your your components in view so here i create a new template tag because this is where all of the html will go for this component now clause nav bar is dark so it's a dark gray color dave claus nav bar brand this is where the logo will go with the name of the site and to use a link in view we create a router link to slash which is the front page class nav bar item and then in here strong canard crm oops close the router link close enough our brand and then below there i want to create a div class nav bar menu and div class nag bar and because i want some buttons on the right side of the screen and then to create the buttons i need a navbar item here as well but this is going to be inside the div nav bar item and if class buttons because i'm going to add two buttons and by adding the buttons class you get a little bit space between them automatically router link to sign up close button is success should be a nice and green button and i want the font in here to be bold or strong sign up close that close the router link i can just copy this replace the two to log in and this can be a light button light let's light gray remove the strong this can just say login now we close that div close that div close that div close that div and close enough and also want to add the simple script here script export default name nav bar script so now everything here should be okay and we are ready to use this inside the app dot view but before i do that we can run this project by saying npm run serve just so we see how it looks before and after so then i just copy this address go to chrome and not much going on here right now this is just a boilerplate code from view but if i go back here now into app.view and then i add a script tag here as well script export default name app and then i would import the component we just created and to do that is the import nav bar from at components slash layout slash nav bar and at just means that we go to the root of the view project where we have the folder components layout and then f bar and we also need to register them here components nav bar great and then to use it i can just copy this go above the router view and say nav bar slash so if i now go back here it doesn't go okay i might be missing a slash there yes so now we've got a navbar up here perfect i've got a couple of errors there or warnings because slash sign up isn't registered as a page yet but you can just ignore that for now and then i just want to add a little bit space above here and to do that go back here and around this router view we say section class section this is a built-in class from bulma great that looks a little bit better okay let's see i see i get the warning now because this should only have one root element in here i just want to add the empty div like that and i indent that great an app.view is like the base.html file in django it's something we want to extend and this is almost like a block template code in django because all of the code that we see here is injected into this and the page we see here is the home.view file so if i just remove this like that go back you'll see that all of the text is now gone great but then i can go back here after this task as well to done next step now is to create a very simple page for the sign up to do that i create a new file in here called sign up dot view i create a template tag template oops like that and in here i want to have a div class container container and i want to div close columns because i want to make this page a little bit narrow to close column s4 and s narrow four so it's centered on the screen there i want to edit title sign up close that no sorry i was not supposed to close that yet form the class field i want one field for the email label email tab class control this is where input field will go input type email name email and class input let me close that close that and i can make a copy of it and have to write all of it password input type password and i want the name to password1 like that then i can make a copy of this and say repeat password and rename this the password too and then i want a simple button for submitting the form table class field david claus control i add these closer so i get a little bit space between them and everything is correct done for bulma button class button is success submit we can close the button go stative like that then i just want to add the script again export default sign up and save and a file inside this views folder it's the same as the page but in order to use it we also need to add it to the router so if i go into router and find index.js you can see that we have the home page and about page so if i go back here now try to go to about i will be redirected to a simple about page but we want to import our sign up page by saying import sign up from dot slash views sign up dot view then i can append it here just making copy of this sign up this is the same url as we use in the app.view then give it a name and say which component we use so a component and a view is essentially the same thing so if we save now go back and click sign up you will see a sign up here on a simple form but it's not on the center of the screen because it's narrow 4 is not a clause it should be is off set four so now it's centered on the screen perfect so then i can set this task to done as well so this authentication and the backend for this will be handled in the next part of this series so now the new steps will be to create a login page first i can just create a new file log in dot view and then i can just copy the contents from sign up because they are very similar rename this to log in i can remove one of the password fields and replace the title with log in and that's i can remove the one there because it's cleaner like that so then i can import this as well to this router log in and make a copy of this replace the url with log dash in log in save go back to the browser click login and now you can see we only have one password field perfect so then i can go back to the to-do list again set this task to done done like that and i also want a simple page for the dashboard so create a new folder in here called dashboard because i want to keep all of the views or pages connected to the dashboard inside this folder to keep things as clean as possible and in there create one more file called dashboard.view and i can also make a copy of the top pair but i want this to be 12 width and this should be a small line so they will be wrapped on the page dash board now i can close this div close this div close this div close the template then we just need the script tag export default name is dashboard like that don't want to add anything more hair for now so i can just go in here and import it i can add this to the bottom but i need to import it first dashboard like that and make a copy of this so when you go to slash dashboard we want to use this view save okay i can't find of course not because here we want to go into slash dash board great so i can try to go to slash dashboard and i see the title so right now we can access this page without being authenticated and this is something i will fix at the end of this video so then i can go back here that this did done because i don't want to do anything more there for now and by the way if you like this video i would be real happy if you click like below thank you and if you haven't already subscribed to my channel it would be super awesome if you did it now and also remember to click the bell to get email notification when i publish new videos okay so now i need to create a simple page for my account and just copy here create a new file inside the dashboard folder my account view paste this replace the title with my account and also this my account and then we need to import this here my account and i copy this as well so the url here will be slash dashboard slash my dash account and we want to use the name my account oops and pass it in there as well so i can now go to my account great so then i can go back to this video list again i set this to done and next i want to configure the view access store ux is a local state handler this makes it easy to check if you are authenticated have security tokens check the load state and similar this file should already be created so if i just find store index.js i want to add a few variables to the state this is variables we keep track of for example is loading that is default to false is authenticated this is also default false of course and i want the field for keeping track of the token and fields here are immutable so you can't just change them directly but to change them we use mutations so here i want to create a function for initializing this view access door this function will be called from the app.view file later so a new function called initialize store pause in state this is done automatically and here i want to check if we have saved the token in the local storage of the browser we do this by saying if local storage dot get item token now we know that the user is authenticated and can say state dot token equals local storage dot get item token and at least the browser will think we are authenticated but it will be checked in the backend anyways just to be sure and we also say state that is authenticated to true but if we don't have this in the local storage we need to just reset this to be empty to be sure and i also want to set the is authenticated to false it's not probably not necessary but i like to do it anyways and i want one mutation for changing the loading status so set is loading state and status and state that is loading equals status so it would be nice if you just could set this in other files but to make sure that this is synced in all of the pages you can only mutate it in this file and i want one function for setting the token set token state token and when we pass in this token we say state.token equals token and state dot is authenticated equals true so now we know that we are authenticated and lost function i'm going to create here is a remove oops remove token this is when we sign out then we just say state dot token equals empty and stated is authenticated is false so we can save so now that we have a simple view extor we just need a way to run this function when we when we open up the website so i'm going to run this from the app.view file view has a few live cycles and one of them is before create this is called before the code is actually finished and presented on the screen so in this file here below the component we say before create then we say this dot store dot commit initialize store so this will actually run uh this function here so we don't have any errors there so probably things are working as it should but we need to add a little bit more things here so if this dot store dot state dot token this is a reference to this variable so we can get it by saying this dot store.state.token so here we check that if this exists then we know that we are authenticated and we want to set the default headers for excels xios.defaults.headers.com outdoorization equals say token space this is very important plus this dot store dot state dot token so now the token is automatically added each time we try to use excels but if you are not authenticated you can just copy this i said oops there i set it to be empty so that if you try to so now that the server in the backend will know that you are not authenticated perfect so we can set this task to done and then the next task is to set up router guards and this is to make sure that you can't access my account dashboard etc when you're not authenticated what this does is that before we enter a route or a page like dashboard we check if you are authenticated and to do that we just go into router index.js and then we need to import the router know the vx store we just created import store from dot slash store there's no access to the is authenticated variable and then at the bottom below where we create the router we say router but before each to from next this is the page we're coming from going to and what we're going to do next create a fat arrow function if two dot matched dot some record record dot meta dot require login and so here we basically check that if we set one of these routes to require login and we are authenticated and we are not authenticated sorry store.state. is authenticated then we go here as a next slash log in so if one of these are set to require login and we are not authenticated we'll be redirected to the slash login page but if not i can just call next which is the page we want to go to so now we just need to tell that the dashboard requires login now do that by saying meta colon require login true copy this paste it down here after my account as well if i now go back here okay here's an error excels is not defined of course sorry forgot to import it in app.view so at the top here import axios from axios refresh now get a new error can't read property common of undefined okay should be headers sorry for the typo okay i can still visit my account page so there is something wrong okay the problem is that the browser actually thinks that i'm authenticated because i have worked on a similar project with this url but the backend would fix this for me but for now i need to go into into application and into here and just clear site data so if i refresh now i will be sent to login perfect so that means that the code here is working and i can go back to the to-do list and set this task to done in this part we're going to focus mostly on django but we're also going to do to do a little bit of view first you can install a virtual environment and install django there i always like to use a virtual environment because it makes everything with the deployment much easier and to install virtual environment is a pip installed virtual enviem oops like that and when that's done you can create a new virtual amaranth and virtual env and then the name which i like to just call environment and then the version of python i'm running which is 382 great and then i can activate it by saying source environment bin activate and then you can see here that the name of the environment comes before my username that means that the environment is activated great so then i can just set this task done and i can go to the next one which is install django and to install django i just pip install django this will install the latest version of django which is 3-2 right now and also a few dependencies great so then i can set this dusk to done then i can install django course rest framework which of course isn't a thing it's django rest framework like that pip install django dashboard framework and django rest framework is a python library we use to create api views and similar so i guess i've tested done and now we can install django course headers this is library to help us with security pip install django course headers set that us to done and then i want to install jose pip install jose and choser is also something else to help us with security and help us with authentication and similar great so now we have installed everything we need on the backend for now and we can go to the next task which is to create the django project django dash admin start project conor crm django great in the folder now the root folder i have the environment gonna set up django i'm gonna send my view so if i just open this you'll see that i have a new file here manage.pi this is a script for running administrative tasks like initializing the database creating super admins and similar in here you have the innet dot pi which is just telling django to treat this folder as a package asgi mwsgi entry points for the web server urls.pi is like a collection of pots and pages for the project and settings that buy is globally settings or configuration for the whole project great so then i've created our django project and we can go now to configure the project because you need to tell china to use the apps we just installed so in here we have something called installed apps django comes with a few of these but we also need to append rest framework and rest framework dot what token gesture django knows that we're going to use authentication tokens and course headers and also joser great and we can also configure the course to tell that where the address for the front end through that you see course allowed origins equals let me create a list and in here we had http localhost 80 oops like that and this is the address for the front-end that we have running here so then there's just one more thing i need to add here and that is inside the middleware above the common middleware we need to add course headers dot middleware dot course middleware [Music] great and middleware this is kind of like the code that is running in the back end of django and this will be executed before most of the rest of the code for django so we checked for security there and that's it for the settings file for now so now i can go back to the to-do list and set this test done and then i want to add the urls for the jose project to the urls page so first i can just remove that big comment and then here i need to append one more function from django.urls called include because i want to include some functions there and then here i said part and every part that begins with api slash v1 and i want to include jose dot urls copy this paste and also want to do the same same parts but also to include what token and save and by adding this we get a lot of cool functionality we can actually create users log in as similar using the api just because of the django rest framework and joser this gives us a lot of magic i'm so much happens beyond the hood now so if there are personality we get now that you don't understand why it's probably because this gives us a lot of important things so then we can set this to done and the next test now is to initialize the database and to do that we just a python managed pi oops let's go into the corner crm django folder and say python manage.pi make migrations to create migrations files for the database and then python managed by migrate to initialize the database so now we get one more file here called db.sqlite3 this is a good database for development and similar but in production we're going to use postgresql which is much better so now we have a database i can set that to 12 bit done and now we want to create a super user so we can log into the admin interface and similar python manager pi create super user and then say admin which is the username i want to use admin at gonna see gonna crm.com and then a password great so then i can set the sdos to done as well and we can run the development server python mentioned by run server this will start a local django server this cannot be used in production but it's very nice and handy for testing things locally so here you can see if you go to the front page that have urls admin and api but nothing on the front page but we won't have anything there anyways but if i go to admin i can log in with the user i just created here you can see tokens and also a list of users only admin so far but later things more things will come here like the leads and also other things that the users of ghana cerama are adding but for now this task can be set to done and we can go to the front end and start working there because now we want to make it possible to sign so if i now just open up this folder src and find the signup view we created in the last part in the previous part so in here i want to do a few changes because when we submit this form we need to call a function and the call function i submit this we say at submit.prevent submit form and we call prevent because we don't want the html or browser's default actions for the form to be called we just want to call this function and then if i just copy the name of that function go down here to edit here i need to add something called methods console.log submit form so when we submit it now we just will see this in the console we can try that go to sign up open up the inspector and now click whoops when i click submit you'll see submit form there perfect and then i need a way to connect these three fields with the submit form and to do that we add another attribute to the input field called v model username and the same for password1 and the same for password no password to of course like this so now we can access this from view very soon just need to add a list of data here so this is a function return now the username set the default to empty password one default empty password to default empty so if i want to check here now i can say console.log with this.username if i go back to view now say something here submit can do the valid email submit but it's printed here now perfect and also if there are any errors in this form i want to show them above the submit button to do that as a div class notification is danger the if i only want to show this if there are any errors and to check that as errors dot errors.length close that div and in here i want p and i want to loop through all of the errors in the list of errors v for error and error and in here i just want to show the error you can see here now there is a warning here and that's because i need to bind the paragraph to a unique key and to do that as a v bind column key error so now a view knows that this paragraph or all of them are unique and then i need to create a new list at the bottom of data like this so if i go back now nothing happens because there are no errors then i need to make a possible to talk to the back end and to do that i say from axios import axios and i also want to import the toast we created in the oops import from excels and i also want to import bulma toast import toast from bulma toast and just remove these commands because in here i want to do a little bit of validation for the data first i reset this dot errors so this to be empty and then i say if this dot username if it's empty then i want to show an error this.errors.push the username is missing and the same with if this.password1 if that's empty then this dot errors that push the password oops password is too short and if this dot password one not equals this dot password two then we say this dot errors that push their passwords are not matching forgot to edit parentheses and then when that's done i can try it out just to see that it's working okay error in errors of course and now i get the recent empty short the password is too short as well great so then i can go back here and know now that the validation is okay and here i can say if not this dot errors dot length then i know that there are no errors and i can proceed by sending the data to the back end and then i just want to add create the object const form data equals username this dot username password this dot password one so only want to send in one of the passwords and what happens now is that we send this to django rest framework and joser which handles the user creations send information to django which then sends information to the database and everything should be stored and to send it to the backend we call excels dot post and then we say slash api one no slash api v1 users this is one of the endpoints that comes from joser and we just want to send the form data variable and when that's done we can say then response this is that we get back from the server and then we want to show a toast to the user to say that the account was created post the message we want to say is that the account was created please log in and the type is success so it's a nice and green success or toast dismissable true so we can exit out pause on hover can be true so it's posted when you have the mouse over duration two thousand milliseconds position bottom right in the lower right corner and when that's presented to the screen also it's this dot router sorry this.router.push slash log in so it'll be redirected to this page when it's done also if there are any errors coming from the server we want to show this as well so catch error so we need to add dot catch if error error dot response that was f4 const property in error dot response dot data and this dot errors dot push then pause in a variable here which is the property which is the field that has the error colon error dot response dot that um property and then we showed the error in here and if it's not error that responds but the error message we need to add that as well else if error dot message there are two ways to get errors from the back end but here we can just this dot errors dot push something went wrong please try again great so now we can save this we don't have any errors here so now the functionality for signing up should actually be finished so we can go here just refresh so everything is okay code code.com and then password submit okay form data is not defined why is that not defined from data of course not form data okay i can try again okay account was created and i was redirected to the login page and i guess that also if i go here to users you'll see that the new user here is created perfect so now we have the possibility to sign up on our crm now we need to make it possible to log in as well so then i can go to the login.view and i can copy a little bit of this functionality for example this and i can copy the v model for the username and also for password one just need to rename this to just password and i can copy the error showing test it above there and i can copy the xcos because i'm going to use excels and i can copy this data array oops like that just need to remove password one like that great and here i also will need the methods list like that submit form like that great and in here i just want to re uh reset the authorization and stuff just to know that we are not authenticated or anything like that so to do that with excels dot defaults dot headers dot com on resection so this to be empty and also local storage dot remove item token then we can create the const form data here as well username desktop username password this dot password and this is also going to be sent to the backend excels dot post slash api v1 [Music] token login so this is another different endpoints we get from jose that we pause in form data and when that's done we get the response back like that and then we get the token from the response and const token equals response dot data dot auth token and we want to save this in the store or the view actually created in the first part so we're going to call this function where we set state token and is authenticated to true to do that is this dot store dot commit and commit is used to call the mutations functions here is a set token and then we pass in token great and then we can also set the the excel default headers to token space plus token and after that we want to save the token in the local storage so local storage dot set item token pass in token and when that's done i just want to redirect the user so this dot router dot push send it the user to the front page but now we can send to my account dashboard slash my account and then i want to copy the catch from here to show errors if there are a name and save so if i now go back here we can try to log in the wrong password unable to log in with the provided credentials okay try a new password submit and that was redirected to my account and we are now authenticated because if not we was not able to access this page great now we can log in create accounts and then the last task of this part will be to make it possible to log out from the front end so it's done from the my account page below this button i want to say div class column is 12 create a button here button at click log out we call this function when we click the button uh this at this shorthand for v on if you didn't know but it's nicer to just add click class button is dangerous it's red so you know that something is going to happen when you click it then we can create the functions or the methods i'm going to use excel shares i need to import it import excels from excels and then i can say a sync because i want to call a little bit of code after the exo's post is finished so i need to make this asynchronous so a sync logout and await excels so the code will not continue before i get the response back from the server post sorry dot post slash api slash v1 slash token slash log out dot then get a response back sorry lowercase and here i actually just want to say console.log log it out and if there are any errors which probably won't be catch error then i just need to show them in the console and we can say json.stringify error because it's probably not anything important there can be token invalidations and stuff but we still want to log out the user so after this code is finished we want to say excels.default.header dot command authorization and then set this to be empty and local storage dot remove item token and this dot store dot commit remove token so the view x is also updated then we can say this dot router dot push slash so we go to the front page when we're logged out so we can go and try this now refresh no errors we get the logout button and we click it we are sent to the front page as you can see here actually got the error from the back end with the 403 forbidden okay but that's not important right now but we are still able to log out so if i just go back here now that this does done and every task of this part is finished today we're going to go through these tasks the first house is to implement a loading bar so that we no one we're getting and sending data to the server in the one of the previous parts we already included or implemented the function set is loading so now we're going to use it in app.view so if i just go to app.view i can edit between the nav bar and the section so here i add a div oops div class is loading and now star is loading bar and has text centered because we want a circle to be centered inside this and then we bind this to clause so if the state is loading then we want to add one more class here so it's loading colon store dot state dot is loading and then close this so if this returns true then this clause will be appended to this list of clauses and in here i want to add one more div clause lds dash dual dash ring and then close that div and close that div and then to hide this when it's not supposed to be showing i want to add some styling below down in this style tag here so first i add styling to the ring i want this to be 80 pixels wide and 80 pixels tall and i also want to set this play inline block on it and then i want to use css to add something after this there and as you can see here i call the animation because i want this to be spinning around so i also need to add the animation css below here like that so when it's starting it should be rotated at zero degrees and when it's finished 360 degrees and then i also need to add styling to the wrapper this one when it's showing and when it's not showing like that so now it's supposed to have height zero when overflow hidden and when it is loading its height should be set to 80 pixels so now we can save this and to implement it we can for example go to login.view and here before we submit this form to to the server first we need to set this function to be async because we also then can set a wait here so before we send this to the server we can just say this dot store dot commit set is loading true so now this should be loading so now when this is true the spinning spinner bar should be showing and after the axios is finished oops below here you set this to false and save and we can also implement this on the sign up view so here we need to change just a sync and then at the top we said this dot is loading actually we can wait until we're in here like that and then await and after that we set it back to false and save so now we have a simple loading bar we can use all over the application so i can set this task to done next step now is to create a new django app for the leads so now i need to go here in the terminal and stop the server and to create the new app we just say python manage.pi start app lead and then it's created so i can set this to done next step done is to create the database model for saving the leads so if i scroll up find gnard crm and then the lead app and models.pi i need to import the user object from django so from django.contrib.org models import user so then i can connect a lead to the user who creates it and then to create a model with a clause lead models dot model and the first field i want here is a connection to the company so company equals models dot chart field max length can be set to 255 and i also want a contact person so let me just copy and paste replace with contact person with a name of the lead and one field for email this can actually be an email field that doesn't need any mx length and phone and also website but maybe not all leads have a website so there we can set this to blank equals true and null equals true so we allow this to be empty and then i want one field for confidence to set how sure we are to get or win this lead confidence equals models dot integral field so this will be a percentage from 0 to 100 blank equals true no equals true in case we don't want to fill it out also want to have one integral field for the estimated value of this lead estimated value this can also be the same type of field and i want one field for status this should be a choice field so i want to create the choices a pair first i want to make it possible to set this to new and contacted and in progress and lost and one and then i need to make a tuple so we can make this a select list choices status equals and then we set new and new this is the label that will show in the django admin area contacted in progress lost and one great so now we can add this here i want this to be a char field as well the max length there can be 25 choices should be these choices status and default can be new and also want a similar like this for the priority so below here i said low low medium medium high high and the new temple here choices priority low oops whoops there medium medium high and high like that copy this pry or right there and this will be choices priority and the default here can be medium and then i want one more field for connecting it to who created this so created by equals models dot for ryan key this is a index to connect it to a user oops user let's let's set the related name to leads so it's easy to get the leads for a certain user and on delete equals models.cascade so when we delete user we also delete all of its leads and i want one field for created at we know when it was created models dot date time field auto now add equals true so when we create this this will be automatically filled out and i also want one more field for checking when it was lost modified modified at equals models dot date time field and here just auto now equals true so every time we save this model this will be automatically set to now great so then before we update the database i need to register this with the installed apps for django and to do that now with the django 3.2 i think i need to set this to be lead dot apps dot lead config i think save try to update the database make migrations yes create model lead and migrate so lead is the name of the app then you have a file called apps which is configurations for div django app and lead config is just the name inside there but now we've updated the database and we can run the server again python manager by run server then i can set this task to done and you can go to the next task which is creating a serializers for the leads a serializer takes data from the database and makes it presentable for the front end and to do that we need to go back into the lead folder here create a new file called serializers.pi first i need to import a little bit from django rest framework from rest framework import serializers and then i want to import the model we just created so from dot models import lead and then i want to create the serializer and i do this by saying plus lead serializer serializer dot model serializer and then we add the class meta for configuration class meta and the model i want to use is i lead of course and then the fields i want to get to the front end should be a new tuple like that and here i want the id and i want the company name i don't remember all of this so i can just go back here copy this list and paste it there so it's just supposed to be company but i want the contact person the email the phone the website confidence the estimated value status priority and who it was created by and when it was created and when it was last modified so i can remove that and now this should be okay so now i can set the mask first done and next we want to create a view this is for showing or making it possible to get this serializers from the front end so then i need to find leads slash views dot pi so first i want to import something more from the rest framework from rest framework import view sets this makes it possible to get a very good functionality from django rest framework for getting information saving information updating and deleting and similar so when we have that we can also import the model from dot models import lead and from dot serializers import lead serializer great so then we can create the view set for this close item view sorry lead view set and in here we pause in view sets dot model view set and the serializer clause we want to use equals the lead serializer and queryset equals lead.objects.org but this will give us all of the leads in the database even if you are not the one who created this so i need to override that functionality by creating a function in here called def get query set plus in self and then just return self dot query set dot filter created by equals request dot user sorry self.request.user so now you only get leads that you have created so then i can set this task to dom and next now i want to create a new urls file here url.buy sorry i forgot to go in here and set this to done so now it's setting up the urls so here is it from django.urls import pod and include and i want to import something from framework from rest framework dot routers import default router and i want to import the view set we just created from dot views import lead view set and then i want to create a default router so router equals default router router.register then we pass in leads so the url will be slash leads to get all of the leads slash lead slash one to get the one with id one and similar and the django rest framework fixes all this for us so here we just need to pause and leave you set the base name equals leads and down down here just a url patterns equals pod can be empty include router sorry router dot urls and save so then we don't get any errors down here so we just need to import this into the main urls file so the bottom here port api v1 and then we also include lead.urls which is the urs file we just created great so now that sauce can also be set to done before i continue i just want to say thanks to my patreons if you two want to support me you will find a link to my patreon in the description below and the next step now is to create a page for showing a list of leads which you don't have in the database yet but we can do it anyway so inside the dashboard we create a new file leads dot view and i can make a copy of this so i don't have to write all of this leads leads and save and we can import this to the router we can go and test all of this so here copy the my account leads like that and we can make a copy of this one for the comma there dashboard slash leads use the leads name and that and we also want to require login is true so if i go here now i should be able to go to leads i see the title leads perfect so next step now is to create a function for getting the leads from the backend and to do that we're going to use excels so if i just go back to leads.view first need import excels from excels and here i also want to use the mount that live hook just like we did in upload view we used a function or live work called before create but here i want to use one called mounted so when this page is mounted i want to call a function named get leads like that now i can create it here methods not the function should be like that and this needs to be asynchronous so i can use the loading bar so async get leads and this dot store dot commit set is loading to true copy this is that set to false and in here i want to call xcos xcos dot get it's important to use the get because you want to get information from the server api v1 slash leads and then we get the response back from the server response create a fat arrow function in here and to store this so we can use it up in the template we can create a data array up here return leads it should be an empty list like that and then to store this we just this.leads equals response.data because response.data is a json list of leads we can use like this and if there are any errors catch error and just show this in the console error like that so if we save now nothing happens here because we don't haven't done anything to present them and change this to this dot get leads so just to see if there are any errors and yes there is yeah i think the problem is that i forgot to activate the tokens for the backend so if i find settings.pi up here i need to add a little bit of code because i need to set that rest framework should have a default authentication class which is token authentication and default permission clauses is rest framework permissions that is authenticated if i now save this hopefully if i refresh i don't get any errors here anymore and here you can see that this was successfully getting the leads from the backend perfect so now we can go back to leads to show the leads which you don't have yet but we can add a simple table below here close that div and then in here i want to show a table so table clause table t head t r t h company th contact person th status so we don't need to add any more there yet we'll come back to this the head body body and close the table and then in here i want to loop through this list of leads using the tr v4 lead in leads and we also need to have this v bind key lead dot id so all of the tr will be unique and then in here we have the dtd lead dot company close that td lead dot contact person close that td lead dot status but there is still nothing here just a table the header you can add one more cost is full width it fills out the whole screen but now we need to make it possible to add new leads so below this title here i want to add a button router link to dashboard leads add add lead browser link now we have this button but this page doesn't exist yet so we need to create it but first we can set this to done and we can go back here now just copy the top create a new file in the dashboard folder called add lead dot view add lead close that div close that template script export default name add lead and then last but at least we need to import this to the router add lead like that and append it at the bottom of this list leads add add lead and save so if i go back here now you will see the title then below here i want a form where i can fill out information about the lead so go back to here create a new column form and when we submit this form we want to call a function called submit form at submit dot prevent because we don't want to send use the default browser functionality we need to call dot prevent submit form i can close close here we can just create this function as well before continue methods so log submit form great so then in here we need to add a few fields we need for all of the information we want so first we can add for the company name div class field label company close the label dave claus control input type text name company and then close i want this to be type of input to get styling from bulma and then we need a way to reference it down here so we need to add the v model attribute company close that and close that so if i have now in here's the data return company set this to be empty by default now i can copy this and say contact person contact person and this can also actually i don't need a name because we need only the v model to connect it to the information down here let's get the contact person default empty and i want one field for email this can be type email email and we can add a little list here email empty and one for the phone phone phone and one for the website website website and website as well and confidence confidence this can be input type number confidence and the estimated value this can also be a number still method value and we also want to make a possible to select the status and also the priority so to create the select list is div class field and we want to label here status close this div plus control div class select i think oh it's probably just select plus select the model status and we need to add this down here as well input no sorry option value new new this here new with the lower case needs to be exactly the same as in the model we created for django option and we can set new to the default status like that this will be selected by view contacted contacted and we also have the in progress in progress in progress and lost and one lost lost one one closed select close to div control and that then we can make a copy of this for priority this v model is the priority you can add it down here and this can default to medium three here low low medium and high great so now we just need a button for submitting the form button plus button oops button is success it's nice and green submit close the button close the div and close the div save we can see how this looks forgot to add a comma down here there great now we have this okay estimated value it's not at the list here zero and the same with the with the confidence zero so now everything here should be okay so if i refresh we don't get any warnings here and if i click submit now you will see submit form which is console logged from this function so now we need to make it possible to send this information to the backend first i want to create an array const lead and then i want to pause in the company oops i don't need this here email email phone phone website website estimator value sorry this dot estimated value because we want to reference this so we need to set this company like this great and then the confidence this dot confidence and status this status and priority this dot priority and then to send it to the backend we need to use excels again so we need to import it here import excels from excels and we also want to use the loading bar here so this needs to be async oops typo async this dot store dot commit set is loading to true and at the bottom of this function we want to set it to false again so then here we can call axios first i'll wait so do i want to wait for this to finish dot post and the address now is api slash v1 slash leads and then django rest framework will handle the rest for us there but we still need to pass in the lead this list like that and when that's done we get the new response you can console this just to see what it is and when that's done i want to redirect us back to the leads page so this dot router dot push slash dashboard slash leads we go to that page and if there are any errors i want to show them in the console console log error and save so now that should be done you can go here and test this try to fill in some random information submit okay this needs to be email submit and i've gotten 400 errors not good if i go to network leads to show what error is this field is required created by yes of course we need to override the default create that function in the back end so just leave this as it is so we can go back to views dot pi in the lead app because now the framework doesn't know which user to set this to so in here just like we did here we need to create one for the save so def perform create self and we also need to pass in the serializer here serializer one like that and we can just call serializer.save and then we can set created by equals self.request.user and save click try again now submit okay we still got a new error this field is required okay so the field created by is missing and the reason why it's missing is because we haven't added it to the list of fields we are sending in yet so if we go to add lead you will see that we don't have it in this list and right now the backend is expecting created by because we have created by in this field list here so we need to move these three just cut them out go up here create a new variable called read only fields and paste them here and the reason why id can still be here is that id is default a read-only field so let's me let me save this now now we can go back here and try again now it was submitted and i was redirected to the front page perfect as you can see here i also had lead here great so now we can set this task to done like that i just noticed one more thing i want to fix and that is if i go in here this is missing some styling so i need to go to bulma dot io to find what i'm missing here so form select and sdiv class select was supposed to be around that like that close it and remove the class from the select element and then do the same thing in here you can save again go back and now you notice it looks much better perfect today we're going to make a portable review and edit leads and also a few other small things the first thing we want to do is to add a link to the leads page up in the menu so if i go to nav bar dot view above here we can say router link to slash dashboard slash and we need to give this a class of nav bar item and then we can just say leads and close the router link so if i now go back to the browser just to refresh you'll see we have a link here called leads but i want this to be at the end here so of course it's need to be inside there like that now you see it better as well perfect so then i can just set this to done and then the next step now is to hide the login button these two when we are authenticated and we don't want to see them and to do that i also need to go into navbar view of course and then above these two here we can say template and we only want to show this if we are authenticated until that is v if store dot state dot is authenticated indent them and then just close that of course if you are not authenticated so refresh and then they are gone perfect and since we have a simple my account page as well we can show a button to that when we are authenticated and to do that below here we get a template v else close that and then in here is a router link to slash dashboard clash my account clause button is info so it's in blue my account and close the router link go back again and now we have the leads button and my account perfect and if we do sign out we will see the login and sign up button instead so then we can set this to done as well and now i want to make it possible to view a lead through that we need one more file in this dashboard folder called lead.view so first you begin the template and a div class container div class columns which is multiline and then one column at the top for the title and the title i wanted to print out the company name so age one class title lead dot title and then below this one i want to have a link to the edit button but we don't have a button or a edit page yet so i just want to add the router link too can just go to the front page at the beginning class button is light edit and then close it and then below this i want to create a div class column s six and then here on the div class box so we can separate this a little bit with some shadow edge to details close it close it i can make a copy of this and the other title should be contact information so we can save this and then we can first before we edit the router i just want to add a script tag export default name lead and then close the script tag then we can import this to the router just removed s and then we find it down here we can make a copy of this and this is supposed to be a dynamic route so we to be able to insert the id here with a colon id and here we want to use the lead name and delete component and save so if we go ahead back now you will see that we have only one lead and if i go to slash one i should go to that page but we don't have anything there yet but and we get this error because we haven't edit the data array here yet return then we can lead the bm object like this so if you're now save go back refresh you'll see the edit button details and contact information boxes and inside of these i want to show a little bit of information so in the details box i want to show the status priority confidence estimated value when it was created anoint was last modified and then inside the contact information on the show contact person the email the phone and the website but we don't have this information yet so we need to make a function to get it from the server first we can say import excels because you don't need this from xcos and then here i want to go into the mounted hook again mounted this dot get lead create the methods list and then we create the async function sync get lead and then first as always is at this dot oopstore.com set is loading true and after we set it to false and then in here i want to call excels but in order to call access i need to get the lead id from the router and get it with a const lead id equals this dot route not a router but route dot params dot id and this id refers to this so we could call this a lead id or something similar if you wanted to do that then we call excels dot get and i need to use these i'm not sure what these are called but you need to use them slash api v1 slash leads and then we want to pass in the lead id here so dollar sign curly bracket lead id and this one makes it possible to pause in variables inside this string but then we get the response back from the server i can just add this dot lead equals response whoops and if there are errors you can just show them in the console like that console.log error and we get the response automatically from django rest framework now because we added the functionality there in the previous video and now you can just add this.lead is the data we get from there because it's the object response is wrong of course supposed to be response okay i get 200 status console.log response to see what that i get from server of course i need to set it response dot there and now some of these are filled in perfect so then i can just remove the console and this should not be leader title but lead.company of course so now we have the company title a little bit of information and similar perfect but this should be a little bit bigger so we need that class subtitle to both of these so that looks a little bit better perfect so now we have the functionality to see a view but we want to make it possible to go from this page into delete so if i just go back to the leads dot view so at the end here i want to add the th this is just an empty one for actions and then td router link to colon 2 because i want this to bind this to javascript i want to use a named route lead comma params and we need to pause in the lead id id lead dot id like that details and close the router link and now save go back we have new button details and when i click it i go to the detail page perfect so now i can set this task to done and then i want to make it possible to edit a lead and to do that i need one more page here so in the dashboard folder edit lead.view so i begin with the template div class container and send title thing and then i say edit and show the lead company after and then below here i have a new column and just close this so everything is okay and inside this column i want to show the form for editing the company and this is almost exactly the same form as we have in the add leads i can just copy the form and paste it but to make it a little bit easier to send this to the backend i want to connect the v model to lead.company and not just companies lead company copy copy paste paste paste paste and paste and paste and this is also there and there and we can change the title of the button to update now we have the form we can add the script tag as well export default name edit lead and i want the data array here return lead and make this an object so then we can close this and we can import this to the router so we can try to go from the detail page to this edit edit lid and then go at the bottom make a copy of this and just append slash edit at the end there edit lead i delete and save so if i now go back to delete.view i can actually just make a copy of this two here so i don't have to write all of it and then i find the edit button and just change this to edit lead and save so now we have the edit button working and if i click it we go to the edit page so now we just need to copy the functionality to get the lead from the backend like we did here copy this then we can go to edit lead and paste it there so now the same thing should happen here so if you're not saved go back you'll see the loading up here but axios is not defined because i haven't imported it import excels from excels save and then we get information in the form perfect so then we just need to make the submit form functionality and that function should go below this get lead and that is a sync submit form then we set the loading above here i said it defaults below and we call patch to the same address as we are on the slash leads one which is the idea for my lead and then we can just pause in this dot lead which refers to this one because this object already has has all of the information and if there are errors we show them like that but instead of not showing anything here i want to redirect you back to the detail page so this dot router.push and then you can say uh this one slash dashboard slash leads and then we pass in the lead id at the end like this so that's actually all the functionality there so if i go back here and click update lead id is not defined no of course not it's up here but i can say this just refreshed remove the errors update and i will send back here perfect okay i noticed that we are missing the rest and modified at and to fix that but before i fix it i can actually set this task to done because now we have the edit functionality if i go in here again now created it and modify that okay so then i need to go to the serializer and i need to copy these two paste them down there so for now refresh i get the information here perfect so the format of this doesn't look very good but we have to come back to that in another part right now i want to go to the next task of the to-do list which is showing a toast when we are saving leads so in here and import the toast import toast from bulma toast and then below here inside the save functionality here i add the toast and the messages the lead was updated and the rest of the information which is the same as designer page so now we can save and try this out edit update and now we have the brimatos down there perfect so we can also add this on the on the add lead page so then we find it i heard remove the console log the lead was added and we just need to import it import toast from bulma toast and save and try that out as well just close this at lead add some random information submit and yes the lead was added perfect so now i can go back to the to-do list and set both of these tasks to done today we are going to add the possibility to create themes for this application so the first thing we need then is a new application or django app for the team so first we can create it but in python manage pi start app team and then we want to add the database model so we can tell the database what information about the theme we want to store so first we can import the user object from django so we can connect a team owner to a team and then we can create the clause for the model class team models dot model i want one field keeping track of the team name which is char field i can set max length to 255 and i want one field for keeping track of all of the members in the team this is also supposed to be the the team owner and this is a management field that means that this team can have many users the related name for the user to the team is teams so once we have a user we can get all of the themes for a user but in our case we just want one team anyway and then we have a foreign key to tell who created the team so we know who the owner is set the related name and when we delete the user we also delete the team and then i want one field for telling us when the team was created and then we can save this so then i just want to import this to the settings.pi file so if i find installed apps you can edit at the baltimore theme dot apps dot team config great so then i can update the database by saying python and it should buy make migrations and python managed by migrate so now we have a database model and an app for the team so now we can go back to the to-do list and set the first task to done next step now is to create a serializer just like we did for the leads this one we need one for the team now so create a new file in the theme folder called serialize and i will need the user here as well so i can go back to mod stop by just copy it and paste it there and i also need to import something from this django serializers there and we can import the theme model as well so from dot models import team great and that's everything we need to import then we can create the user serializer because we want to serialize the information about a user in a team so clause user serializer that serializers dot model serializer and here we need to set the class meta and the model we want to use is user which we just imported up there and the fields we want for all of the users or all of the members is id username first name and the last name i don't think we have added this to the application yet but we will later so we can just a dimmer anyway and we won't want serializer for the team so clause team seria lysor pass in serializers dot model serializer and we want one field here for the members so we just want to tell the team serializers that's where the members field this one we want to use this serializer numbers equals user serializer many equals true because it's more than one object and read only equals true because you don't want to be able to create users through the team serializer we just want to get information about the user then set the class meta again the model here is of course the team and the fields we want to get for the theme is id name and members and save so now we have the serializers for the team and we can create the view so we can go back to view i'll open up view.point at least so we can remove this because you're not going to render anything but we need to import view sets from the rest framework resets and we need to import the theme model from that models import team and from the serializers import team serializer we only need that because the other serializers we used is only in here and then we can create the view set for this so class theme view set you set dot model view set i need to set which serializer class we're going to use and that's the theme serializer and query set equals team dot objects dot all so we get all of them and then let you override the get query set like we did in the other view set so def get query set self return self.queryset.filter created by equals self.request.user here we also need to override a perform create functionality because you need to connect a user to the created by field and also add the self.request user to the members so def perform create you need to post in self and serializer just like that we know us on the end and i will say obg like short for object equals serializer dot save created by equals self.request.user now since we now have the object here we can say obg dot members dot add self dot request dot user so now the user will be a member of the team as well obt.save then we have that as well okay i forgot to add that we need to add the urls here as well to make it easy i think i can just make a copy of the one inside the lead i create a new file urls.pi but here we want to import the team view set of course this can be teams copy replace and teams so it's that they are identical so we can just close this and go back to gonna jungle and find the main url stop by because we want to import it here part api slash v1 include team.urls great so now the django app there is finished and we can set this task to done now we can run the server again so we have it running perfect we got no errors so the next step now is to store user information in view x because we need this later to connect the team to a user so before i continue i just want to go here and log out the user so i can log in again and get the information from the server you can open up this we will see here if we get an errors so now go back to store slash index.view index.js and here i want to add the object user id can default to 0 and username can default to empty and then in here when i know that we have a token we also would have stored a username in the local storage so here we can say state.user equals localstorage.getitem username make a copy of this and rename this to id and user id so we store them as username and user id in the local storage and if this this is not the case we need to set state.user 0 state.user.username to empty and i also want a function for setting the user so then i can just say set user state and now we get the object which is user state dot user equals user so now we need to implement this in the login function as well so if i scroll down and find login.view i just want to make this a little bit smaller so at the bottom below this await excels i want to create a new excels function and i also want to pull a weight on this because i want to do it before the loading is set to false so await excels dot get and to get information about the user we can say slash api v1 slash users slash me and this will give us the id of the user and the user name this is default from joser dot then and i get the response create a fat arrow function and then we say this dot dollar sign store dot commit set user and then we create object id response dot data dot id this is the id we get from the server and then a username response.data.username and this object here is the one we are sending and getting here which is the user and it contains the id and username great and when that is done we can save the information in the local storage local storage dot set item username response dot data dot username and localstorage.set item user id response dot data dot id now we have information about the user here then we can console.log if there are any errors console.log error and close that and one important thing to do now is to just copy this from there or cut it out i mean because we can't redirect you here we need to wait until this is finished so in here we move the router push to the my account great so now we can save this and set it to done but we can test it just so we know that everything is working so if i go back to the browser log in then i'll log in with the user i created in the previous part okay that's wrong there okay and now everything here should be okay this is just because i didn't log in on the first attempt so if i go back you can just test that we have this information then in this here after we have initialized the store we can say console.log this dot store.state.user save go back and you can see here we have the id and the username so now we have information about the user stored locally as well perfect and i want to do this exact same thing but just for the team so we have information about the team name and the team id in the view x as well so i can just go back here again and then i say team like this an object id 0 name empty and i can make a copy of this because we need to use this as well so team dot name and team dot id i want to store this as team underscore name and team underscore id now is estate oops dot team dot id zero state.tm.name equals empty and before i forget it i just want to log out again so we don't have any problem but with not having this information in the local storage and then below the set user we say set team self team state team equals team and we can actually use this function to store the local storage as well local storage set item team id is team dot id and local storage dot set item team name steam dot name and this object we will get from the front end very soon great and that's it here for now just save this and we can set the toast to done because i don't want to add this to the login view quite right quite yet because uh i need to fix this that if you don't have a team you will be sent to a create team page because we don't have a team in the back end yet or in the database so this is done the next task and that's actually quite easy because you can just go into upload view and after this has been set we can say if not this dot store dot state oops dot theme dot id so if this is not set and zero will also return false and we say this dot router push slash dashboard slash create or add team so when don't have a team now you will be sent to this page i can set this to done and if i now go back here log in user yes as you can see here i don't have a port called slash dashboard slash add team but we will create it very soon and that's the reason why i couldn't be redirected there but the next step now is to create a page for adding themes so in the dashboard create new file add team.view then i can copy a little bit information from one of the other pages copy this top add theme close it close this div this and the template and then let's create the script tag export default name add theme script and then i can go back to the router and import it here add team and scroll down and i can make it copy of this for example add team add team and add team if i go back now refresh you'll see that i see the add team great so now we need to add a little bit more information here because here we want a form and i think we already have form in the add lead so i can make a copy of this whole block here and then just to remove a little bit from it paste it below there i only want one field actually like that so this can be renamed to name or which is the name of the team or team name to be extra extra sure and then rename this v model to name and when this is submitted we call the submit form function methods submit form like that and here i also want to use the axios and the toast but i can copy from this i don't have to write that now like that and we also need the dead object here to connect the name field to down here so data return name and it's default to empty of course and then i just want to take one more copy and that is that is loading functionality so paste that there paste unzip defaults and then in here i can say await excels dot post post slash api v1 slash themes and we want to pass in object called team and no i have not created it yet so i can go apparently const theme equals object name is this dot name which is the information from here which you get from here great then we get to do then response and when that's done we want to add the toast so i can copy that from this page as well and the router push paste the theme was added and when that's done i just want to redirect this back to the dashboard page and when the theme is created we get information about the team back from the server automatically so here we can set this dot store dot commit set theme now we just want to pass in object here id response.data.id and the name which is response.name and this we can just say this.name since we have it here already great and if there are any errors we need to show them dot catch error fat arrow function console.log error and save so if i now go back okay there is a little error yes sorry i forgot to add async here great so now we can try to create a team code with stein submit the theme was added but i see an error here state is not defined so the theme was not set okay why okay the problem is in here i think this should not say self it should say state so great so i can save that and we can go back to the to-do list and set this to done because now we need to fix the login to implement themes as well so when we log in we get information about the team we just log out we can test it out when it's finished the first thing we need is to create a view for this so if i find the team up here first i need to import a little bit of functionality from the rest framework from rest framework import oh from work dot decorators import api view and i also need to import one more thing from rest framework dot response import response because you know we want to create a new view a little bit more manually let me say api view decorator that this view should only accept get requests and then we can create it then we can create the view by saying death get team request actually it should be get my team and then we can get the theme i think team equals team.object.filter created by equals request dot user now we want to get the first in that list serializer we want to use for the team is team serializer now i can just pause in this object and we get the information from here as well so then we can just say return response serializer dot data great so that's the view and then we want to import this to the urls so append it after there get my team and then at the bottom here is a pot teams slash get my team and get my team name get my team and save so now we should be able to get information about the team from the back end that we need to make a little change to the front end as well so if we just go back to login.view we need one more function like this so await excels dot get slash api v1 teams get my team and this will give us information back and here we can then say this dot store dot commit set theme create the object id response dot data dot id and name response.name now i've stored this in view x and when we do that we also save it in the local storage here automatically great so then we can move this router push down here actually and we can console log the errors not there but there great so save that but before we test this i just want to go to my account page and where we remove the token from the local storage i also want to remove user name and user id and team name and team id like that great so then i can go back here try to log in like that okay i got a 404 error on the team why so that should be okay but it might be because of the order here that it should be like this because if not i think this router here thought that this could be the id of a team or something similar so try to submit again now it was logged in and everything looks okay so we can go back to upload view just to confirm that we have the team name so here is a console.log this dot store.state.team [Music] and then yes id1 name codewithstein perfect so now we have information about the team and the user as well here in the front end so then after this task they're done today we're going to make it possible to add members to our team but the first thing we need to do then is to update the lead model so if i just scroll up here and find models.pi and the thing i need to do in here is to connect the lead to a team so at the top here we need to import the theme model from team dot models import team and then at the top here we can create one more field team equals model dot foreign key so we can pass in team here and set the related name to leads and on delete models.cascade great now we can update the database i've done measured pi make migrations and now i need to set a default theme because this is a required field so press one and here i just want to say one because i know that one is the id of the only team i have created so there and then i can say python mentioned by migrate great so now we can run the server again and go back to the editor and then i need to make a little change to the views.pi because now it was not possible to get all of the leads connected to your team and not just the one you created yourself so first here i want to get the team by saying team equals team dot objects and now the members in equals self.request.user and what this does is sorry this needs to be a list so what this does is that you check if one of the members is in this list which is you as the user so if you are in the list of members then you get the team but since this is a filter we will get the list so we need to set first there to get the theme object and then down here i can say filter theme equals team and before i forget it i need to import the team model from team dot models import team and then i need to do the same thing in the perform crate because now we need to connect the team to know the lead to the team as well like this so now there are no errors i can go back to the to-do list and set the first ask to done next i want to make it possible to add members i don't want to invite them by using email yet i just want to make it possible for the team owner to add members so first you need to update the views find the theme app so scroll up and find views.pie and then here i can do the same thing as i did or blessings and members in equals convert this to a list like that so now we'll get all the themes where you are a member we only want to get to the first like this and same down here instead of just getting the one where you are the owner you want to get where you are member and only the first one so that was the views.pi changes so now we have make it possible to use members instead of just the owner i can set this up to click done and then i need to update the serializer.pi in theme as well there because i want to pause in the creator here so below here i can say create that by equals user serializer this is not the money field but i want it to be read only crew then i can pause it in here so we can know in the front end as well who the creator of the team is so we can go back and set this to us to done before i continue i just want to say thanks to my patreons then we can start moving to the front then because now i want to make a page where we can show which team you are on but i just want to log out first and log in just to see that there are no errors in the things that i've done so far yes as you can see here i got an error now self is not defined in views dot pi now here should just be a request to the user and authorized together just type the wrong password now everything seems to be okay so then we can go to the next task which is to create the page for team so in the dashboard folder we create a new file team.view and then i can just get a little bit information here or code and we say team like that close this and attack the tag now the script tag export default name team and just close the script tag and we can import it to the router so we can test it it's working like that and if i now just copy this remove the add and save so now if i go to the nav bar i want to add this up in the menu together with the leads router link to dashboard slash theme plus nav bar item team and we close the router link now we have the team appear perfect and the theme title here is showing great and then i want to show a list of the members here h2 class sub title members close the h2 and then i need functionality to get to the team from the server methods get team and we also need the data array here return team members and this can be a list so i just set numbers here so that we appear can loop through this because if i don't add it there it will just crash table clause table is full width t head tr th name don't need anything more there for now and below the head with that deep body tr v4 member in theme.members which is a reference to this one team dot members v bind key member dot id close the tr tv member.username because we don't have the real name yet great but if you now go back you'll only see empty table now i need to make this function and also i want to call it when this page is mounted this dot get team so here i think i can just go back to login.view and make a copy of this and also that one so we can have the loading great copy add it to the top there set it to true and i think get them so now i don't want to call the store but we can say console.log response dot data and i do not want to redirect to the account page so now we can see what we get from the server excels is not defined of course not import excels from xcos save refresh and now actually got a list of members here great which is me as the user but twice this showing there that's because this.theme equals response.data yes and now you can see my username is shown there perfect and response.data is an object which is exactly the same as team because we have a members in there and similar and instead of showing just team there maybe we can say theme.title teamlot name of course like that team name and then the members perfect now i want to make one more page for editing members but now you can set this to done and then i would make possible to add members to do that i want one more page so make a copy of the top pair create a new file add team member.view add member close the div template and then the script export default name add member save now we can import this to the router add member find team because i want this to have slash team first add member add member save and then in here i want to have the button below the title router link two now i want to use a named route so i need to connect this to javascript so we had a colon too and name is add member and where the class button is primary and member are no errors so it seemed that this was working yes and the good thing about using this instead of hard typing the urls is that we can use the add member and if i now go in here and change this you don't have to update the code everywhere you use reference to this page great so now i want to add a form here so i can actually just copy the signup form so copy all of this go back to add member paste it and yes that's it there and i can copy the sync submit form functionality methods paste it there okay i also need to copy and a couple of other things like this data array i also need to import these to the excels and the toast great now i will change this later in this series because i want to make it possible to invite users and not just add them manually like this i think i want one too many curly braces okay just seeing that everything here is okay change this the toast to the member was added and i don't want to go back to this here i want to go back to name team okay so now i think i can save that no errors here great so now let me try to add a different user code to another password submit okay the member was added but it's not here and that is because i was just editing the user like this so i need some functionality to connect this user to the theme and to do that i want to add one more view to themes.view here i want to add a new api view post because i just want to accept post requests death add member request and then i want to get the theme and i also need to get the information from the front end because you need to pass in the email for the user so data equals response actually i think i can just say email like this email print email just want to see that to actually get this this way email return response this can be empty return and then i want to say user equals get user.object.get name equals email then we can set theme.members.ad user team.save great and then we need to add this to the urls add it at the end there just make a copy of this at member add member and add member great so then we can go back to the add member view and we can copy all of this i can wait with this take it out and just append it at the end here instead no that's not correct it will have to be in there sorry and here i say themes slash add member and email data and create a new object const email letter email this dot username can remove this and then we can try again because now we will call this pause in the email address and then we will get it in the back end and append it as a member got no errors so we can try code three submit okay button error response is not defined now that was probably supposed to be a request dot data so we can try again [Music] okay that was a very long error submit and i got the same type of error again user is not defined imported it appear from django.contribute.models import user save let's try it one more time okay now it was added there perfect but i see here that i got an error why did i get that okay we can try one more time just to see what's going on submit and now everything was working perfect i think the problem was that the user made was actually exist before so this should maybe be moved inside here we can try that because now we won't go to this if the user isn't created so let's remove that line then we can remove the weight on that axios so let's try one more time just to see that it's still working code it's time to this user already exists so i just want to see if i get an error now yeah user test already exists so we don't go through with this but if i add one that doesn't exist everything is working perfect so now we have the functionality to add members to our team nice let me just try to log in with one of those members code it's done five and yes i can still access this theme perfect but this should not be available for this user but that is something i have to fix at a later point but everything here is now working in this part you're going to make it possible to assign a lead to a member but first i want to make a possible that only the owner of team can add members to do that you need to go into team.view up here where we show this add member button i only want to show this if we are the owner so here we can say template the if team dot created by dot id equals store dot state dot team no sorry user dot id if these two are the same this will be rendered so close this and save we can go back to the browser to see this if we go into team there is an error can't read the property id of undefined that is probably because i need to add this object down here temporarily before we get it from the server so refresh and now the button is gone and i think that is because that this is stored as a string in the database so if i pause and save now i have the button there perfect so that was task one finished and we can set it to done so now the next step is to make it possible to assign leads to a member and to do that we need to first update the lead model because we need to add information here about who the assignee is so find models.poi in the lead app folder and then above created by i say assigned to equals models.char field sorry foreign key of course user object the related name can be assigned leads on delete models dot set null because we don't need to delete it just because we delete the user and since we can't set this to null we need to make this possible because not all leads will be assigned to a person so now we can save that and we can go back to the terminal so we can update the database make migrations and migrate perfect now we can run the server again so we have it in the background and we can go back here and the lead model is now updated so you can set that it's done next step now is to update the lead serializer because we want to get this information to the front end so here above create that assigned to and you can add it at the bottom or wherever you want i just want to have it here and we want to have more information about the user right now we'll just get the id so up here we can import the user serializer from the team from team.serializers import user serializer and then we say assigned to equals user and that read only to true because we don't want to create a user when we create a lead great so now we will access this information in the front end as well you can set this to done and to make it possible to assign a user need to override the update function in the views.pi file just like we do here is a team we need to do the same thing but with the assigned to user so here we need to create a new function [Music] def perform update self serializer and then in here i want to get the object obg equals self.get object this is the current lead we have then member id equals self.request.data this is information we get from the frontend assigned to so this will be a user id and then we can check if this exists so if member id then we know that we have assigned it to a user i need to get the user from the database objects dot get pk for primary key equals member id and since we are going to use this we need to import it from django from django.comtrip. dot models import user and down here we can say serializer dot save assigned to equals user so now we'll save this and set assign two to the user we have selected in front and and if the member id isn't there we can just say serializer.save and there won't be a user assigned to it great so now i can set this to done save and the next step now is to find the edit lead so we can add the functionality here to select which member we want to assign to so i can copy this since this is a select list and instead of saying priority we say assigned to and this should be lead dot assigned to we're gonna have one empty first error select member [Music] now we can set this to selected then if i just remove one of these and then i want to make this iterable because now we want to loop through all of the members in our team so we bind value member dot id i want to say v4 member in team dot members and v v bind id member dot id so it's unique okay i get an x say because this should be the bind key of course and then here we can show member.username like that great so now we just need to make it possible to get this from the back end because now we don't have access to the theme on this page so here you can say team make it an object and in here needed numbers just so it doesn't crash before we get information from the backend and then here we can say theme and we already have a function for this in team.view so here we can copy all of this function get theme go back to edit lead and just paste it below the submit form like this so then we can save this try to go to the browser and test this then i just go to leads go into a lead edit it then i have the select list here and i can choose code 2 update the lead was updated and i don't got any errors as i can see perfect so if i just now go back here you can set this to done and done and then the next step now is to show assignment in the list of leads so leads.view here after a contact person we can say th assigned to close the th and here again td here i want to use the template the if directive lead dot assigned to so if this be if sorry so if this has a value then we can show it so lead dot assigned to dot user name and close the template like that and also close the td save so now go to leads you'll see that this is assigned to call to perfect and this doesn't have assigned into person perfect so now i can set this to done as well next step now is to show the assignee in the list detail page and to do that i can just make a copy of this and go to lead.view and i want to show it here above the status i can use this v if here as well so p strong assigned to close the strong and close the p like that if i now go into this you will see assigned to there perfect and this doesn't have assigned to a person yet great so then i can set this task to done as well today we're going to go through these tasks which are making impossible to add clients and similar so the first thing we want to do then is to have a list of clients in the crm to do that i can copy the lead.view because much of these will be the same if we just copy all of this content and then create a new file called clients.view then again paste it here and then i can just start renaming it a few things like clients and dashboard clients add add client and and i want to loop through each client in clients and bind the client.id to the key and this can just be like this for now so you can do down here first if i replaced clients there as well and clients and get clients get clients and i can just do this for now like that actually now i see here that there was an error here just go back and paste that first if we have not added a way there so let's just fix that before i continue here i can add it here as well await excels great so now we have this functionality and up here i want to say name which will be the client name here we also want a contact person but i don't want the assigned to and we don't need a status here either so we can just remove this so here onto a client dot name and client dot contact person so you know who the contact person for that client is and we want to link this to the client detail page client.id like that so now this template should be ready to move that there so it's a little bit cleaner so now we can import this to the router at the bottom import client from dot slash views dashboard client dot view at the s there as well of course so if i now scroll down i can go to the bottom you can copy the leads paste it clients clients and clients and save so the next step now is to just make a link up in the menu so we can go to this page and copy this as well clients and clients and save so you can now go to the browser we have a new button here clients like that perfect but we don't have anything here yet so we can show a message saying that to the user up here over the table you can say template the vf client.length so then we will render the tab ball close that template vls you don't have any clients yet i can close that paragraph and close the template and save go back and i will save this message perfect so now we can set this task to done and then the next step now is to make it possible to add clients so first thing we need is a new django app and database model so i can go to the console and stop server python managed by start app client oops rmfr clinic it's a typo client right before i run the server i want to fix the model and also register it with the settings.pi client.apps.clientconfig save and then we can go to the database model again i think i just want to make a copy of the leads model because i want a few things from this so just copy all of this content close it then we can go to client models by paste it there and here i don't want the status and i can rename this before i forget it but i want the theme but we need to rename this to clients and instead of the company here we can say name and i want this information but we don't need confidence or estimated or status or priority and not assigned to either but it's nice to know who created it and when it was created and similar so then i can save this and then update the database python mentioned by make migrations and python mentioned by migrate so then we can run the server and now that we have a separate model for the client we later here can add notes and similar just for the clients and not for the leads so then again that is first to done and we can work with the serializer and again i just want to make a copy of the content of the leads serializer and then create a new file in here serialize search.pi paste it here we want import client and replace lead with this you don't want it assigned to here so you can just remove the user serializer client and then rename company to name remove these four values and save so that was the serializer done then we can create the views so again just copy this go back to here and paste it in views.buy and here i want to import the client and also the client serializer and call this client view set and the serializer class i want to use is of course client serializer and i want to use the client model here besides that this can just be the same and perform update there there i can remove this like that actually i don't need the perform update here i think and this can be the same perfect now we can save this and create the urls file just want to set this task to done first and then the urls.pi file so it was a lot of copying now but it's okay create a new file urls.pi import a client viewset rename to clients and rename to clients and that was it there so now we just need to import this to the main urls file and gonna see that i'm trying to go there alt api slash v1 include client.urls great so now we should have access to the clients from the backend so we can set this to done and we can set this no no you can now start making possible to create client in the front end so if you now make a copy of all of this content in add lead.view create a new file add client dot view and paste it we can start replacing a little bit of things like add client place name with name contact person we want email phone website remove these two remove this one and also that one the rest of this can just be like this and we want to rename this to add client and we can remove these four values rename this to client and remove and replace with clients client the client was added and re directly back to slash clients great and that was that page so now i need to import this to the router add the client like that so then you can scroll down copy this client slash add here we'll just add client client like that so now i think we can set this task to done we can go and test and also this that we can test it just to make sure that it's working at the client here just a client one contact person the email gmail.com one two three four five six seven eight maybe google.com and submit and that did not work but the 500 error assigned to is not valid for model client no where is that okay i forgot to remove assigned to from here so save and we can try again now 400 bad requests okay got an error because the website is empty or missing from this list so add that there refresh you can try again no i've got the same thing with name because this should be named that probably goes here as well like that sorry okay refresh now there's no errors so we can try again submit and now the client was added but it's not showing here in the list yet and that is probably just because we removed this so if we remove this comment here replace this with clients and this with clients save got a new error no match for that okay it's because i haven't created the detail page 4 client yet so up here you just want to remove this for now refresh and now we can see it is perfect so then we can go to the to-do list again and now we should have this which is already done actually the only thing missing is the link to the detail page so if i go back here just undo so we have it back here again but if i save now the page here won't work but we're going to fix that now by creating the detail page client dot view by the way a few weeks ago i started a new discord server for coded stein so if you want to come there and chat with me or some other subscribers for my channel please come and join us there i will add a link to this in the description below so just make a copy of the contents of lead.view paste it and start replacing get client that also forgot to add a weight here so just go back to lead and fix that before i continue save clients list.client client id client and client great so then this can be elected confidence and estimated value can be removed status and priority and assigned to can be removed i can remove this edit lead link because we don't have the edit page yet but we can rename this client dot name and also this client no lead should be replaced and save so now this page should be finished and we can import it to the router like that let's import that and we can copy this and just say colon id i won't use the client name and the client component or page so save refresh now the details page or button is showing click it and it will be sent here and get information about this client perfect so that means that everything here is also done now page for the client and we also get the information from the server so this whole task can be set to done and then we just want to make possible to add the client so still going to copy a little bit of the lead copy the whole file create a new file and that lead dot view sorry edit client.view so we can begin up here by renaming this to client.name name and it should be client name of course client.contact person planted email client.phone candid website remove these two remove remove and also remove and this can just be like that add it client replace this with client and just remove the team because they're not going to use that in this in this page and remove the get team function [Music] like that and then replace the get lead with get client client id clients client like that clients and this dot client which refers to this object which gets information from the server at first clients and client id so we can then save this because now everything here should be finished and then we need to import it to the router edit client edit client and append it to the list here slash edit edit and save great so now we just need a button a pair for going to the edit page so let's just copy it from here again go back paste it edit client client dot id and save so now refresh just go here we have the edit button and if i try to edit there edit it also change up here and update and now it was changed perfect so now we can add view and edit clients as well perfect so i can set this task to done done and done and done so now that we have the possibility to do all of this with the client we are going to work more with clients in the next part of this series today we are going to make possible add notes to a client and also edit them and show them and after that we're going to make possible to change information about the users so this way you can add the first name and last name to users first going to start by adding notes to clients there we need a model and i want this to be a pair in django of course and in the client and models dot pi and then here we can just say clause note model dot model and here i want the team field so i can just copy it from a pair rename this to notes and i also want a reference to the client since the team can have multiple clients so client equals models.foreign client related name is notes and on delete equals models.cascade and then i want the name for note i can just copy it from here and a body which is a models.txt field like i said is the blank equals true and all equals true in case it just won't add a name of a note in the first great so that's the model so we can go to the command line and update the database python manage.pi make migrations and python managed by migrate great so now we have the database model for storing nodes in the database and that's the first task done and then we can go to the serializer i still want to be in the client here first you can import note a pair and then below here class note serializer serializer dot model serializer class meta and the model is of course note and the fields i want should be id and i want the name and i want the body i don't think that i needed team or client so i just leave it for now so now we get this task to done and we can continue to create a view set for this so in used pipe we first import the node model and then we import the node serializer and then at the end here we can create a class note for note view set view sets dot model view set because we want all that functionality like create edit view and delete and then serializer class is the node serializer we just created query set dot object at all and i think i can just copy these okay first i can copy the get create query set there because i want to filter them by team but i also want to filter them by the company no the the client id and to get the client id i just want to use the request.get.getparameter client id so i can pass this in in the url and dot filter client id equals client id and it's okay to say client underscore id because that's basically what this actually says this is a reference to the client id but django fixes all of the other things for us great so now we can get this based on the client and the team perfect so then we need to copy the perform create oops there okay so we use the theme and we created by i didn't add decorated by to the database but we should actually have that so i can copy this and okay we can also have it created so we just know when it was created and also the modified and that replaces with notes now we need to update the database again first make migrations okay i need to add a default value to this i can choose a time zone dot now and i also need a default value for this and here i also want to pass in one which is the id for one of the users so then i can migrate and run the server so then i can go back here again so now this will be filled out perfect and also modified and created that will happen automatically okay and here to get the client id i want to get this the same way as here now we can actually send this in the as a post data so client id equals request dot data client id and then we set client id equals client id like this i hope this should work so that's it for now we can go back here set this to done now we just need to import the things we created to the urls page so inside client you're asked by here we include router.register notes note view set and the base name is notes i also need to import this here and save so now most of the things in the backend is finished and we can go and create a page for adding notes so in the dashboard create a new file add node.view and i can make a copy of one of these since we have since we will have a few of these fields so just copy the content of add client and paste it there and note and we want the name but we don't want the contact person but we can rename this to body and instead of an input field here we want a text area and it can have that v model but i want to close off text area and then just close the text area and the rest of these fields can just be removed so now we only have the name body and submit button great we can rename the add client to add note and instead of saying all of this just want a body which is default empty create a new object here note we want the name but we don't want this for her so that we can remove this and here we want to pass in the client id we are on so client id this dot route dot params dot id because we are going to be on a specific client id when we add this so this client id is the one we get here in a request.data and we pass in there great so that we can rename this to notes and pause in the note object and then note was added and here i want to redirect you back to the client page so name client and params id client dot id which is not existing but we can replace it with this route params.id like that and then everything there should be okay so we can save this now we need to import it to the router just make a copy of one of these add note and we need to find the client detail page there like a copy of this or we can make a copy of the edit actually add note or add dash note add note and save and then the last thing you need to do to test this is to go to client.view and then we need to add a button here so first we can add a jar just to separate this a little bit div class column s12 h2 class subtitle notes and then a router link column two and then i can make a copy of this add note and the id is client.id because that we have access to here add note close the router link and close the div and save great so now you just notice that there are no errors perfect so now we can go to the browser to test this if you go into client one here now add the notes here and we have add notes button or link so just click that i just want to open this so we'll see if there are any errors yes contact person where is that this of course should be body save refresh and error is gone note one the body submit okay got the 500 error request is not defined okay i think that is okay because they should probably just be self dot request and self dot request save again try again submit and now the note was added perfect and no errors in the backend so now there should be a note we can show here perfect so that means we can go to the to-do list and set this task to done and we have also sent the information to the server so now automatic was able to show the notes on the detail page of a client we can go back to client.view and here once we have uh array notes like this should just be empty and after this.getclient i can say this dot get notes or i can just actually do it in here so yes remove this and i can create a new excels in here like a weight axios and then i want to copy this notes and just add question mark client id equals like that remove the last slash there so this client id here will be the one we get here in the requested get parameter perfect then we get the response dot then response list of notes equals response dot data and if we get the errors we just show them in the console great save now refresh no errors but no notes so we need to add them appear the load router link div class box v4 note in notes v bind key so it's unique no dot id and then h3 class is size four and we want to show note dot name there and the no dot body and close the div so now we have no tear but the body is missing no body but why is it missing we have it here in the serializer and the model it's named body yes it's because this says this.contact person body i didn't see that i didn't replace this so it should be desktop body so now it should work by creating new notes you can create one more note 2 the body of note 2 submit and now it's shown there perfect okay i just want to convert this add node to a button so close button is success great and then mb6 so you get a little bit space below it perfect so now we are able to add and show the notes and then we just need to make possible to edit notes as well so the first thing we need then is a new page edit notes dot view and i can copy the add note because much of this will be very similar add that note the name the body and this can just be like this or you can update this to update actually i want to change this to edit note of course and this should be note which is an object and then instead of saying here we can say note.name node.body which means we can remove this and instead of sending in this we say this dot note so just pause in the note we are on and the note was but updated don't want to use a post request here we don't use a patch because then the back end knows that we want to update this and the rest of this can just be like this now here i need to import the no insert the note id this dot node dot id and i need to change this to backticks so we can pause in variables in here great so now i just need some functionality to get the note from the back end so mounted this dot get note sync get note and we made this functionality many times so we can go into one of the other pages and copy the content here so just copy the whole function from for example lead i want to get a note id from the parameter it should be note underscore id notes and note id and this top note equals the data we get from the server great and that was the whole edit note page so now we need to import this to the router so at that note pass it in there scroll down and we can copy this one because there's a add note here i want to say add that note and we need to pause in the note id here so here we get the client id if you want that later but we also get the note id edit note and edit note and save so then we can go back to client.view and then we want to add the edit button below this body to do that i can just make a copy of this one replace it with edit note i want to pass in the client id but also note id colon note dot id edit note so now we have the button for editing great we can try to edit this one okay we didn't get information from the server get the 404 error and that is probably because i didn't pass in the client id so we need to go back to edit note and then here say client id equals and pass in client id and we can get it the same way here oops const client id equals list.params.com id so now we have information note 2 and the body of two changed update and the same problem is here now that i didn't pass in the client id to the update page so i think if i just pass it in like that copy the functionality to get the client id save i think that's it so it changed yes now it was updated perfect okay i need to fix this button because it looks kind of weird because they should use mt6 so margin top six instead so we have a space bit above instead of below the button great so then we have possibility to add view and added notes so i can set this to done this is done and then this is done and the next step now is to add an endpoint for getting information about the user i want to just add this in the user profile know the team functionality here so in serializer here we're going to use this serializer because the first name and the last time is already fields on the user we just haven't used them yet so here in the views.pi to create a new function here so at the top here we can import the user serializer and we also need to import a few things from the rest framework from rest framework dot views import api view i want to create a custom view for this functionality and we also need to get the response we already have that there and we need status so here we can just append status together with view sets status and then we can create below the team view set since this will be a clause if it's here very well close user detail and i will pass in api view there the first function i want to create in here is a get object function so we can very easily check if an object exists so def get object self primary key try return get user.objects.getpk equals pk and we've already imported the user at the top there and if it doesn't exist we can say accept user dot dos not exist race http 404. that means we need to import this as well it comes from django so from triangle.http import http 404 and this function here will be reused throughout this class so now we want to create the get functionality which is almost the same as the get query set appear def get and it deposits itself the request the primary key and format equals none and then to get the user we say user equals self dot get object pause in primary key so here we use this function and we just want to do this in case we want to edit another person which is not ourself the serializer we want to use is of course user serializer and here we want to pause in the user and then we can just say return response serializer.data so this essentially does the same thing as this thing here so we can get the user but we don't get all of the other functionality but there is a reason for that and that is i just want to make this a little bit simpler and it's also nice to know how to use this api view so if you now just copy this go to urls.pi you can import it here then we can pause it in the top pair part you can say themes as the the first part in the url user or member and here in pk which is the user id i want to pass in user detail dot s underscore view make it a function name user detail and save so now it should be possible to get information about a certain user from the front end and then to check that that is working we can go and create a new function here edit member dot view and since this is added page i can go to edit note copy all of that see as much of it will be the same edit member here what megabots will edit first name user dot first name and last name sorry copy this because it's supposed to be an input field last name and then the update button and here i want to rename this to edit member this can be user this dot get user get user and then the user id should just be params.id like this and then i want to post in the user id here user id themes slash member and then the user id this dot user equals this great and we want to use this here when we are updating it afterwards as well we haven't created the backend functionality for this yet but it's coming soon here we need to pass in the user id and we want to send the information from this.user to the backend the user was updated and then i want to send you back to team like this remove one of those perfect oops sorry this should be members also teams slash member and save just want to see that there are no errors perfect so if i now go to team where we list out the members it should actually redirect you back to my account because right now we just want to make it possible to edit your user so now go back to my account i can add a button here first div class buttons so we get a little bit space between these two buttons and then the edit button if i go back to for example lead i just need to copy one of these named routes i always forget the syntax for them like that edit user post in store.state.user.id which is your user edit and i want to indent this as well and now we can close the div and save if i now go back to my account i get the error here okay i can't find edit user no of course not i forgot to add it to the router so first import it added user pass it in there if you now find edit i can find the team actually edit member and then pause in id like that edit user and refresh can't resolve edit user okay what did i call it edit member and it remember it's what it should be called all over the place actually [Music] save refresh still not working no okay go back to my account again replace it with edit number now we have the edit button there perfect and i don't have a name for me yet but i can try to change it code with stein update and this will of course not work because we don't have anything in the backend to receive this data so that's the next step now we just need to go back to views.pi and in here we need to create the pet functionality but it's almost the same as patch so self request pk format equals none and then we get the user the same way as hair and also the serializer but here we also want to pass in data equals request dot data which is the information we get from the front end now we can check if it's valid if serializer dot is valid then we recall serializer dot save and return serializer dot no sorry you're supposed to return this like that and if it's not valid is a return response serializer.errors and status equals status dot http 400 bad request because then there's something wrong okay no errors just try to submit this again but we got a new error it's not allowed okay there i made it work by going in here again and changing patch to pet so if i now go to edit i get the code with stein name perfect now we can change information about the user and in the next part of this series i want to show it here for example show the name instead of the username and other places we use the full name of the user great so if i now just go back here i can set this to done oops and estidon they stood on today we're going to make it possible to show full names in crm create a button so we can convert a lead to a client and also create a model where you're going to set up the plans for the teams and later we're going to implement this so we have limitations on how many clients and leads a team can have before they need to start paying or upgrade their plan so first we can do this on the leads page so if open up leads.view and instead of just showing the username here we want to show the first name and the last name so make a copy of this and last name if i go back here now you'll see john doe instead of just the username so it's much easier to understand who it's assigned to and the same thing should be done in here on the detail page so open up lead.view and just replace the username with this now is your name there as well perfect and then i think you need to do the same thing here on the members page so this is team.view and you can actually show the username instead in case someone wants to know what it is full names we can add one more th td and save okay there was an error yes because this should of course just be member that first name and member dot last name we have the email and then the name there perfect for refresh the error is gone as well great so that that's the first task to done and we can go to the next one which is converting a lead to a client to do this i need to create a view in the back end and if i scroll up and i find the client i think you can put it in there so here i want to create this i just need to open up the team app because there's a few things i want to copy scroll up i want to copy the api view and the response we can actually copy all these four and django http as well so then i can go back to the boosted pi for the client and paste this here and i can remove this one and i want to put this in the middle there so it's alphabetically great so if i now scroll to the bottom oops i can create the view here so i begin with the decorator api view and i only want to accept post requests parentheses around this and i want to create just a simple function based view here because it's easier for the task we're going to do and then def convert lead to client request and here we want to get the theme just like we do a pair because we only want to convert leads if you are the owner of or if it belongs to your team this should be requested user and then we want to get the lead id from the form or the button we are clicking on in the front end lead id equals request dot data lead id and then try because we're going to check if this lead exists so lead equals lead dot objects dot filter theme equals theme dot get primary key equals lead id and if it doesn't exist we can write accept lead.dos not exist so now we know what the error is and we can erase http 404 error okay see i get a little line under this because lead is not imported so above these two models from lead.modules import lead so we have that imported as well and then below here when we have delete we can create a new client so client equals client.object team equals team and name equals lead.company so i can copy the model from the lead so i know what fields we have here we're going to use a few of these i think it's this one at least just paste them here for now so we have them there and this so it's just the same for fields here great so now that we have the name we can also set the contact person equals contact person sorry lead contact person and email equals lead.email and then we have the phone and website phone equals lead.phone website equals lead.website so now i can remove this so now when this function is run we will get the lead and i'll create a client based on the information we have in the lead and we can also set the created by so we know who created the client created by equals request.user and that's all the fields we need there now we can return response and this can just be empty great so if i now copy this you can import it to urls like that i want to add this at the top here part and then we pass in this name and add a name and save so now this will be possible to reach from the front end by going to slash api slash v1 slash convert lead to client now we just need to create a button in the front end so if we scroll down and find lead.view then we can create a div here first div class button so we can have a little bit space between these two buttons and then button at click convert to client convert to client close the button close the div we can add a clause to this clause button is info now we need to create this function so when we click this button we call this function this should be a sync first we can do this so we add the load loading bar false and we also want the lead id here as well and i can make a copy of this paste it there but this should be a post request and it should not go to leads but convert lead to client const data you can create the data object to send in lead id lead id and if you then just append this at the end here they should be now sent to the back end console.log convert that to client and then we can redirect the user to the clients page so this dot router dot push slash dashboard slash clients and save so now we can go to the browser and test this just see that there are no errors so now i go to lead go into this one now i have the new button here click it convert that to client and now under clients i have apple as a lead perfect so now i can convert a glade a lead to a client i've added this you'll see that i can configure the information we have stored about this client perfect and i can add the notes as well so it's just a normal client great so if i now find the to-do list can set this to done oops and then next to us now is to create a model for the plans for the teams so if i scroll up and find the team app models point then above the team i can say class plan models dot model then i want the name so i can copy this this is just the name of the plan and i can say max leads equals models dot integer field default equals five let's say that three users with a maximum five and maximum clients can also be maximum five and we want the price for this so we can have a monthly price price equals models dot integer field default zero since there's a default price is zero for the free plan and then we can set a default string representation of this return self.name so it's easier to see in the backend what plan we are on and i also want a reference from the team to the plan so at the bottom here we can say plan equals models dot for ryan keem and pausing plan related name equals team actually teams so you know all of the themes a plan has on delete models dot set null because we want to have this field possible to set null so null equals true and blank equals true in case you are not on a plan but then you know you're on the free plan anyway so save this stop the server so we can update the database make migrations and migrate under run and i just want to make these two available in the django admin area so you can check that everything there is working from dot models import team and plan an admin.site.register team admin.site.register plan save so if i now go to the admin area we see that i have the themes and the plans here perfect so let's add the free plan price zero max five and small team we can have 15 leads and 15 clients it should cost 10 dollars per month and big team 50 leads 50 clients and 25 so you see the free small and big theme perfect and if i now go to teams find my team i can assign this to the free plan for now but we are not going to do anything in the front end today for this so i can just go after this to done great so that was the beginning of the plans thing for this crm project hi in today's video we're going to add search functionality to the crm so as you can see here if i try to search for test i will only get company with the name test in their name and i can also search for john she gave me the same thing because the contact person is john if i remove this you can see this if i search for tim i will only get contact person tim great and we will also add some simple pagination i just go back to the code i just want to show you if i change the page size to two refresh you see here i can go to the next page back again and only go into the end the next button is gone so let's begin with the first task which is add pagination to the leads page so on this page i want to go have a next and previous button so the first thing we need to do now is to go to the code and find the views on leads so here the first thing i want to do here is import pagination from the rest framework from rest framework dot pagination import page number pagination then i want to create a separate clause for the lead pagination clause lead pagination and then we pause in the clause we're going to use there and i want to set the page size to 2. you can increase this later it's just for testing since i just have a few leads for now and then i can just set here pagination plus equals lead pagination save and if i now go back and refresh i get an error okay i think it's because the data has changed a little bit so if i find leads dot view just want to run a console log on the data we get okay already done that there so here it's now data dot results response response.data.results fresh and now i have two of these perfect and then as you can see here i also know what the next url is supposed to be not there but if i say console.log result response.data.next then i know what the next url is supposed to be there just to go to page two great next step now is to go to page two if there are a page to so i want to add a show next button set this default to false and show previous button also defaulted to false and then in here we can check that if response.data.next and then we know that we get a next page from the backend this dot show next button equals true and the same with previous so if response.previous then show previous button is true and if i do this now console.log response.data you will see here that we have a count of five and we have a next this shows the urls but the previous is set to null so now we will get the next button if i scroll up and below the table i can say div buttons button class button is light the if show next button next so if you want to show this button this needs to be true so if i go back now we have a next button but it's not working so i need to fix that now and add click go to next page and then we need to create this function i think this dot current page plus equals one and then we call this dot get leads again like that this does not need to be a thing sorry but we need to add the current page up here and the current page is one so then i can save and we need to post in the page here as well if i change these to backticks i can pass in a variable here page equals this dot current page so we can pause this in even if it are still just on page one so refresh now and if i now click this we will go to page two click one more time we get this but now this is still showing and that's not correct and that is because on the top of get leads i should say this dot show next button is false and this dot show previous button equals false because we want to reset this every time so then i can make a function for go to previous page preview this page and there we can just say this dot current page minus equals one and this dot get leads then you can just make a simple copy of this button go to previous page and we only do this if show previous button and change the text to previous and save if i now go to the next page we will get the previous button there but i want this to be on the other side of course like that so now we go there the next button is gone if i go back now okay this that go to previous page a little typo then i can go back and when i come to the first page the previous button is gone perfect so now we have pagination on the leads page and i guess that is done but before i forget it i just want to increase this to 10 which is a much better number to work with instead of two so then we just need to do the same for the clients page so if i copy this scroll up to client paste it at the top here and then i want to import the pagination here as well from rest framework dot pagination import page number pagination change this to client pagination and then we can just pagination class equals client pagination can set this to one so we can test it here as well we'll now go to clients don't have any clients that's because of the same error i think so i need to find client.view clients sorry and instead of saying this that classifies most of that out you said this response data.results so now we have one client there but we need to add the next and previous button again i can make a little bit copy of some of the code so we can copy these three go back to clients paste them in the data array and we can copy these two methods and paste them here but we need to change this to get clients like that and then i need to convert this to backticks so we can pass in the variable page equals this dot current page and i also need to do some changes in here because i need to reset these two buttons and then last but not least do this so we show them based on if there are an extra previous page and the last thing you need to copy is the buttons so below the table paste it save and refresh now i can go to the next and previous because i only have two clients but the pagination there is also working perfect so let me guess that this is done before i continue i just want to say thanks to my patreons if you two want to support me you will find a link to my patreon in the description below and then the next step now is to add search to the leads so inside leads here below here i want to have a search bar so we can begin with that if i go back to leads then here adelaide hr form dev class field has add-on add-ons maybe dave claus control input type text and this is class input close the div and then we need to have a button button clause button is light search close it close the div close that there and close the form now we can check if i did correct yes it seems to be correct but we can have a different color success for example great now we have the search thing there but we need to connect the field to the data array down here so we can say v model query then we need to add a query set it default to empty and when we submit this form we want to call a function or a method so v or at on dot prevent because we don't want to submit the form to the browser submit form but this is not correct um this is how you write it at submit dot prevent sorry just paste it there then we can copy the submit form and create that method like that console.log you want to check the query this dot query and save very fresh now and i want to search for apple you see here down here that you are trying to search for apple great so then we just need to send this in to the back end and i can do that as well by using the get leads functionality so what i can do then is to say this dot get leads and a pair in the same pages here i can say and equals search sorry search equals and then we can pass in this dot query because if it's now empty it won't give any results i think we can try this out just refresh yes we can still get data from the back end so i just want to go to the back end now and activate the search so find the views with pi in the leads page and i need to import here with the views as filters from django or django rest framework and in the lead view set i need to set something called a filter backends equals filters dot search filter so now i can use search and this is going to expect a keyword called search and then i need to define what to search for so search fields equals company and also on the search and contact person these two are fields from here you can search and add these if you want to just do this for testing and save refresh i will get everything here now probably because this is empty but if i search apple now i only get apple back great if i search a i get all of these five if i search test i only get test company perfect so that's everything we needed for the search so this is something called build this is built in into django rest framework and what we did here in the front end is just pause in a keyword or parameter called search and get and let me just pass in whatever we are typing in here so now i can set this task to done and then i just want to do the exact same thing for the clients so here i can copy these two fields and find the views to apply there paste it here but here i don't have a company so i need to use name and i need to import filters up here save so that's everything we need to do in the backend it's so easy to add search like this so then it's just the same changes in the front end and actually when i think about it i can just remove this submit form button and instead up here where we are searching i can just say get leads like that and i can make a copy of this little thing go to the clients page start adding it here as well so append that there we can append the query here like that and then we just need to add the search bar here as well so copy this go back to clients save not get leads but get clients save refresh go to clients and now this is there a search client i only get one and if i search apple i get the other one perfect but before i forget it i just need to change this to 10. so we can now refresh remove the search we get all of the clients in my list perfect so now we have search functionality in our app great today i'll continue working on the plans so first you're going to add some plants limitations in front end and then we're going to make a simple subscribe to the plan page he's not going to use stripe yet but everything else will work and the first thing we need to do to implement plants limitations is to go to the back end and then serializes the pi in the team app we need to add a serializer for the plan so first we can import the plan here and then above the team serializer we can say class plan serializer posing serializers.model serializer and then the meta information we want here is model equals plan and then the fields oops and we want the id and the other fields we want there is the name the max leads the max client and the price so name max leads max plans and price plans like that and then we can add it at the bottom here as well so if you just say plan equals plan serializer read only equals true now we can append it here at the bottom like that so then when we use the function get my team we will get the information from the team because here we use the team serializer so we need to use this in the front end as well so in the index.js we have this team object we want to create three more fields there plan can be a default empty max leads and default this to zero max client and default this to zero as well and then we want to add some more info here as well three more of this plan max oops max leads max clients you can store it like this max leads max clients now store all of this information also in the browser now we want to reset this plan max leads our max clients you can default this is zero so it's integrals and at the bottom here as well we want to set this so make it copy team plan the max leads and tmx clients great so now this should be stored in view x and also in the browser if it refresh and when we log out and log in we'll store this so a little change i think we need to make is that inside the login view i just want to test that information we get here is correct so here we redo this i want to set say console.log response dot data and as you can see here we only pass in the id and the name but we want to pass in more here so we can do this it's a little bit cleaner plan response dot plan dot name suppose the data.plan.name max leads response.data.plan.max leads and max clients response.data.plan.max clients clients like that so now i can go here and i can log out because i get an error let's from the back end feel the max plans is not valid for model plan max plans no clients of course refresh the error is gone great so then i can log out and log in again code.go.com but if i now see in the console.log here you'll see that we have the plan object here with the id the max clients max leads and the name and this is the current plan for this team perfect so then we know that we have this information and we could show it here in the theme page so let's do that just so that we know what plan we are on so in team blood view we can show this information here just add an hr we can actually add two just to separate this a little bit p strong plan and that one should be store.state.team.plan i think it's correct one closed sp yes plan three p strong max clients store.state.team.max clients make a copy of this between them clients to leads and max leads perfect so now we have that information here so now if i go to leads page for the clients page if you have more than five clients i want to hide this button and i show a notification instead so just copy this and then i can go to the leads page then here i can say template the if or i can just add this vf to this button the if if this number is greater than the number of leads we have for this team then we need to create a new variable called num leads we can default this to zero but here in get leads where we get the leads from the back end since we use this for filtering and similar i think we need to do this two times actually if i just make a copy of this paste it here like that and then i can remove the page generation filter from here and then i want to just console log this because i want to see what we get from the back end so if i go to leads and just refresh you see that have this count five that means that we have five leads for the for this client and then i can say this.num leads equals response.data.count and then automatically hide that button there perfect and that means that the limitation for the leads is now working but when we reach the limit we want to show a button or a notification here so div class notification is dangerous it's a red notification the else to just show this if this is not rendering you have reached the top of your limitations please upgrade so now we see this instead of the button perfect and then we want to do the exact same thing for the clients page so here we can add this to this one [Music] but we would use max clients of course and num clients i can scroll down and add it to this list default this to zero i will make a copy of this as well this dot num clients equals response.data.account then i can remove this limitations like that so if i go to clients this is now showing because we only have two of the two clients for this this theme but i still want to show the notification here if the limitation has been reached so we can just paste this there so we if nvls great so now i've implemented the limitations for this project and then the next step now is to if we go into team we should have a plans button here so you can go into a plans page and subscribe or upgrade so then the first thing i want to do is to find team dot view or i can set set the first task to done just so that's done and then let's make it possible to subscribe so below here i can add a new paragraph and then router link to and then we'll do the name plans like that close this change plan close the router link remember to add a colon here so we're buying this and can use this in there and then we save and i will probably get an error because that page doesn't exist so we need to fix that a new page plans dot view then i can copy a little bit of this plans close the div with the div close the div close the template and then i want a little bit of this script and copy all of this and close the script tag rename this to plans now we don't have any data here yet and we can remove the content from mounted but everything else can be like this then we want to import this to the router just make a copy of one of these plans plans and if we now find team we can add the url here plans plants and plants great now we have this change plan button and if i click it we'll see the plan's title now i want to list out three plans we have available here the free the small and the big team so then we can add some columns there div class column is four table class box then we have a subtitle in here class three and then an h4 class is size three and here we can say zero dollar or dollar zero like that and i will make a few copies of this small theme that price for that i think was five dollars ten dollars the big team which is 25 dollars per month so now go back here you'll see the free and then the small and big team and then below here we can add p let's say max five clients close that max five leads for the small team it's 15 clients 15 leads and the big team i think i said 50 clients and 50 leads you can change these numbers like you want it's just for testing for me now and then below this here we can add a new button button at click subscribe you know we can pass in small team subscribe close the button but you want to add a class to this close button is primary okay copy of this big theme and we can also have this on free in case you want to downgrade save now we have the information about what the different plans gives us and the subscribe button so when we click this button we want to tell the backend that we are subscribing and now we want to be redirected to a thank you page so before i continue i can just create that simple thank you page by copying all of this content create a new file called plans thank you dot view thank you and we can remove almost all of this thank you for subscribing to a plan plans thank you oops you need to close that paragraph and save now we can import this to the router so we have a place to be redirected to thank you and append it after this one thank you oops like that so now i can just close the router on this page because we don't need anything more here but we need to create this functionality as well here so methods subscribe plan like that and here we want to set the and here we just want to go and copy a little bit from a different view so i can copy this one just all of the get leads and paste it here then i can remove one of these i can remove the get button like that and sorry about this a little bit messy like that and set this to sync so we want to set this to is loading when we go into it and remove the loading bar when we finish then we can create a dead object to send to the back end const data plan plan so we post in which plan we want to subscribe to and we don't want to get information here we want to send information so we need to use the post just to remove this teams and we want to upgrade plan and at the end here we can pause in the dead objective right here so we can get the plan in the back end and when that's done we just want to redirect us back to the themes page so this.router.push dashboard slash themes but since we have subscribed to new plan we also need to update the data we have in view x and the storage in the browser so um just like we do on login you can just make a copy of this and go back to plans so when this is finished we can call this again and get all the information we need from the backend and then we can redirect you to the teams page so then i don't need this one like that or we can have it there and just console log it so you see that everything is okay upgraded plan and then save so just want to check here that we don't have any errors so now we just need to create this view in the back end so if we find the team app go into views and we can say at api view here we just want to support post requests def upgrade plan request and then we want to get the theme just like we do on all the other views here plan equals request dot data plan then we should get the name either free small plan or big plan or a big team print plan plan so we can see this in the console as well for the server and then we want to get the plan from the database so we need to import the plan here plan like that if plan equals free then plan equals plan.objects.get name equals three lf plan equals small team plan equals plan dot objects dot get name equals small team i think that's the name for it big team and small team yes perfect else or lf plan equals big team plan equals plan dot object.get name equals big theme so instead of using this way to get it we could add for example a slughair or something so we can use pause in small theme like this in the database so it's easier to get but this works as well and then we can say theme.plan equals plan team dot save and then we just say return response and we can actually just return this data just like we do with get my team i can do this here and save so now we get all the information we need in the front and if we go back here we can copy this content all of the content from then the response and paste it here so now we don't need to call two times to the server so that should be it i think so we can try to test this now refresh we don't have any errors and if i click this i get a method not allowed and that's because i forgot to add it to the urls file so i need to copy the name of this go to urls import it and then path teams slash upgrade plan pass it in and set the name as well now we can try again just refresh so the error is gone subscribe and i was redirected but this page doesn't exist because it's supposed to be just team and now my plan is small team and have the mx clients and max leads perfect i just want to fix this to redirect you to the correct page great now we should just show a simple uh toast so we know that we have changed the plan want to copy this from a different place there was a toast the plan was changed like that i just need to import this or import the toast to have it available like that save now we can just try to do this again change plan subscribe the plan was changed and it's still small team perfect so if i now go to leads the add lead button is back again perfect so what's left for this task or everything is done for today but we still need to implement stripe and that will be done here so when i figure out which plan to subscribe to we will send the information to subscribe to stripe as well today's part we're going to install stripe and start implementing it a little bit the first thing you want to do is install stripe to our project and to do that we need to go to the command line and stop the web server and this is installed because you just need to run pip install strike and that was actually the first task we've done already so we can set this task to done now we're going to continue with stripe and the first thing you want to do is to create a stripe account i've already done it but you need to do it now just go to stripe.com and sign up when you're done that you're going to get into the dashboard and here you have a button called developers and in here you have something called api keys these are something we're going to need in this project so first just click the publishable key to get it and i need to go to settings.pipe and here we're going to edit so add a command stripe and i'm going to stripe pub key equals and then paste it in there and a reveal test key to get the secret key this is the one we're going to use on the server which no one should know about then i copy this so nana says stripe secret key equals and paste it in there and save so now i have the two api keys here so i can then go to the to-do list as you can see here next test was to create set this to done and then the next step was to get the api keys and next i want to create two products because i want one for the small team and one for the big team so go back here and then we have something called products and we can add product small team and its pricing should just be standard pricing change this to us dollar and say 10 recurring monthly and save product so then we have this we can copy this api id because this is going to be needed to buy this product you can go and add this to the settings.pi file as well stripe price id small team equals like that and we want to do the same thing for the big team big team this can be 25 i think it was the price recurring a monthly and save product so then we copy the api id again create a new variable there stripe price id big theme equals and paste it in and save so now we have the api keys for everything we need for now from stripe so i can set this task as well to done and next up now is to make the public key available in the plans page so i need to create a new api view so i can get this from the server i could just paste it statically into the view file it's just that then you have to do this twice when you deploy this server similar so it's easier to just do it the right way so in the theme we can have it here create a new api view at api oops api view this should only use get death get stripe key request and here we can just say the key equals settings dot stripe if i can go back here now copy this name the public key it's important that it's not the secret game like that and obviously i get new error here that's because we need to import the django from django import settings i think now this is supposed to be django.conf import settings so we can access variables in settings.pi file and then we can say return response and then in here i think we can just say pub key like this and save see if we get any errors no not for now at least so we can copy this go to the urls and then we can add it here it might be a little bit weird to use the team so we can call it something else in here stripe slash get api key now we paste in this name like that and now we just need to append this to the list of views so this is the address we want to call to get the publish key from server i can save this and we can find the plans.view page and here i can say key default is to empty but when we mount this we want to call this dot get game now i want to call this function a sync gets put game like that i can copy this loading here false then i want to get it from server so i can copy this just modify it a little paste and instead of saying upgrade there we should say stripe get pub key i think that was the address if i go back to urls get stripe webcam like that i guess i console.log response.data just to see what we get from the server dot error catch error of course in case we get any console.log error great so then we can save try to go to the plans page team change plan okay this just keeps loading data is not defined there was no error as i can see response no sorry this data was not of course and this needs to be changed to a get request sorry okay so if i'm now refresh you see that we got the pub key here so now it's available and i can say this dot pub key equals response dot data dot pub key so now we have it available in this template which you're going to use when we submit the payment to stripe so now i can find my to-do list and i can set this task did done and then i just want to initialize stripe in front and to do that i need to find a file here in the public folder called index.html and below the title here i want to say script src https slash js.stripe.com v3 and then close it now we have stripe included but we need to initialize this also on the plans page so here i want to create one more variable or property called stripe scan default to null and when we mount this we want to say this dot stripe equals stripe and we use the strap we included and then here was on this dot key the problem now is that we can go to this before this is finished so we need to set this to a sync i'm going to wait for this to finish before we go to the stripe and initialize it so if we save now refresh just get a warning here that says that we're using http but that's fine for testing great so now we have also initialized stripe great so then i have that last task to done and in the next part of the series we're going to do the rest of this where we are going to make it possible to click this and then the payment will be sent to straight we get information back using a web hook and then we can finalize the payment today we're going to finish the implementation of stripe first you need to add some new fields to the database specifically to the team model so if i find a team app here and models pi i want to add a few new fields here i want one field for keeping track of the status of the plan if it's active or if it's cancelled so plan status equals models dot char field and i want this to be max length of 20 because we don't need any more here and i want this to be a choice so choices equals choices plan status default is plan active like that so as you can see here we got this error and that's because these are not defined up here so i need to fix that now plan active equals active and plan cancelled equals cancelled and then i need to create this tuple of statuses so now it's a tuple and then i first pass in active and then the cancelled great so now i don't get any errors here and then i want one field for keeping track of the customer id which this theme will get in stripe so stripe customer id equals model.char field and the max length can be 255 because this can be a little bit long but this should be more than enough blank equals true and null equals true because if you're a free team then you don't have this and i want one for stripe subscription id and this is to keep track of if the subscription is valid and similar there so now we can save this and go to the command line and stop the web server and then run make migrations to create a migrations file and run migrate perfect got no errors and the database is now updated so we can run the server again so when i go back to the to-do list you can set this task to done the next step now is the download and install stripe cli we need this to test the books from stripe so when we send the payment to straight we need to get information back to us from stripe and check that everything is okay so if i go to this address you'll get a description of how this is done so install stripe click you can see here just download this and then until it or unzip it and i've already done this so if i just go to cd downloads you'll see that i have a stripe this is executable file and then i need to log in which should be the next step here stripe login sorry dot slash stripe login and then i hit enter to open in the browser great so now i got this here and this is the same code as you can see here if i click allow access you may now close this window and return to the cli so now this key with this here will be okay for the next 90 days i don't need to keep track of this right now and then i need to set up this cli to forward requests to our api we do that by saying dot slash stripe listen forward to and then the address to the server which you can see here is one two seven eight thousand slash api slash v1 stripe slash web hook i will create this page soon so if i hit enter now see that it wants me to upload but i don't need to do that but here i got a webhook signing secret i need to add this to the settings.pi file so go back here and i will say stripe web hook key equals and paste it in there and save so now that should be okay and i will come back to creating the hook later when we come to that part so now i can set this dose to done and then it's finished stripe implementation it's a very big tasks but i will try to split it up in pieces anyway so the first thing you need to do is to go to plans dot view here you need to change this subscribe function here because you can just tell the server to update our plan for free so command comment out this for now then you can create a new excels dot post this should go to api slash v1 slash stripe slash create checkout session and this is information we send to stripe from the server and then we get information back from them now we pass in data so we know which plan we have selected if it's the big team or the small team and then we get response back from our server response oops here is something wrong like that and then in here we can set console.log response just so we can see what we get from a stripe and return this dot stripe which is a reference to the one we initialized here dot redirect to checkout and then we pass in something called session id response.data.session id this will get from our server and we will create this after we finish with this and if we get any errors we just want to show that for now catch error console.log error error and save so now everything there is okay but we still need to do some more things in the back end before we can start testing and in the settings.pi i need to add two more variables here i want one variable to where we are going to be sent after the payment is finished and if we cancel the payment front and web site success oops to access url equals http colon localhost 8081 which is my address right now dashboard slash team slash plans slash thank you and this page we created in one of the previous parts so it will be sent in here to plants slash thank you and then you have the front and not success but cancel this is if you start the the payment process but click cancel and we just send you back to the plans page like that and then we're going to continue so now i want to create this function which will call strive for us and get the session id back and then we know that everything is okay so if you now find team views dot by we can go to the bottom and edit here at api view here we want to get post data def create checkout session and then we pause in the request parameter and here we want to initialize stripe but we haven't imported stripe so we can do that first so if you just go to the top you can import json because you're going to need that and import stripe great so now we have stripe imported and we can scroll down to the bottom again and then in here is a stripe dot api game equals settings dot stripe secret key so now use the secret key instead of the one we publish and can show in the front end want to get the data from the front end and we do that by saying json.loads because you just want to pass this right straight into json request.body and the requested body is the data we have in plans if i find that file is the one we pause in here so we can get the plan and then when that's done we say plan equals data plan so then we know which plan the user have signed up to and if plan equals small team then we want to say price id equals stripe price id small theme and this price id is the same is the same thing as we got in the previous part else then price id equals settings dot stripe price id big team team like that great and then we want to get the theme for the current user so we can just copy one of these and then i want to use a try cat share because it will either work and then we get the session id or if not we'll just return the error to the user so try check out session equals stripe dot checkout dot session dot create and here we pass in client reference id equals team dot id and then we create the success url which is the one we get from the settings front and the website success url question mark session id and this should just stay like this because stripe will fix this for us when we are redirected back and then i want to set the cancel url which is just the one we set up in the settings pi file and then i want to set payment method types just add chord here and mode equals subscription and line items should be a list and then in here a dictionary price this price id is either small team or big team and quantity is of course one in our case so everything there should be okay and then below here is a return response session session id checkout session id since this is something get from stripe and if there are an error we can just accept exception as e so we get an error return response error and then we pass this into a string e and that's it for this view so now we can import this to the urls file for team just paste it at the end there then port stripe slash create checkout session pause in the view and set the name to the same and save so if everything here should be okay we still need to do more work but it can be like this and we can go and test if we open up the inspector to see here if i now click small team we got information from stripe and we got redirected here perfect it also set the small team and us dollar ten but the problem is now if you continue the web book will not register that the payment is okay so we need to go back as you can see here we go to the cancel page which is this now perfect so then we need to set up the webhook so stripe can talk to our website and this is done in views.pi first i need to import two things i'm going to import http response this comes from django.http and i also need to import a decorator from django dot views dot decorators dot csrf import csrf exempt because we are going to get a post request from stripe but we they don't have this csrf token for us so we need to make it possible to send us a post request without that but only for this view so we add this decorator like this and then def stripe web hook request and then we initialize the stripe by setting striped api key and then we get the web hook key from settings as well settings dot stripe web hook key and payload request.body this is information we get from stripe and also get the signature header from stripe which you need to use in order to check that everything is okay event equals none now we can say print payload payload let's see what information we get from stripe and here i want to use a try catch as well so try event equals stripe dot web hook dot construct event pausing payload sig header and the web key so this information is now sent to stripe so this is the information we get in the web book the signature header and also our webhook key accept value error s e then we're getting value error return http response status equals 400 but there also an other accept error so accept stripe.error.signatureverification error that means that there's something wrong with the signature s e return http response status equals 400 and then below here we can check that if the success or if the payment was successful i do that by saying if event this is the event we get here and the type is this because there are many type of events there then in here we can say session equals event data object and we get this session information from stripe and then we want to get the team based on the information we get back from stripe and to do that we said team equals teams object to get our primer key is the one we get there and this is the one we set up here where we pause in team.id to the current user and then we want to set the stripe customer id which you get from stripe and the same with the subscription id so we can check the subscription later and then just call team dot save great and then at the end here we can say return http response status equals 200 to let no to let stripe know that everything went okay so now we just need to import this to the urls file add it to the end there pod stripe the book like that scrape that book and name is also stripe webhook and save so now we can test the next step here if you try to click subscribe so then we can go ahead and try to use go ahead with the payment so try to add my email here and then record information this will be a successful payment and then just add a date in the future cbz123 stein it will now click subscribe processing processing this should look okay and then as you can see up here i was redirected to the thank you page and we got the session id and this we're going to use to verify the payment so if i now go to the console you'll see that we got some information okay they gotten 404 error that means that that book didn't work apiv one stripe web hook okay let me try to check the urls file this should be straight slash web hook sorry i need to try this again so if i just go back to the plants page click subscribe let me do this again subscribe and if you now follow here this was successful successful successful perfect and everything there should be okay now great so now we have this customer id and similar in the database so now we just need to check that this is okay and then we can set the date for the end of the plan for this user so now we can go back to views.pi and create one last view here just copy this paste it and def check session so now we want to check this session here requests and then we can initialize stripe again here and we can create a new empty variable called error then one more time we used it try and then we want to get to the team because we need this paste it in there then we get the subscription from the team this should be added when we got the stripe hook down here so we can compare the information with what is stored with stripe and then we get the product which is the big team or the small team and if everything is okay now we can say team dot plan status equals team dot plan oops plan active team dot plan and date equals date time dot from time stamp subscription oops subscription dot current period dot no underscore and this we get from stripe as you can see here now i've got this error because i haven't imported thai date time yet so below here from daytime import date time scroll down again then we can say team.plan equals plan.objects.getname project equalsproject.name will either be big team or small team we can call team.save and then we want to generate information about the theme and send it back to the user so we can copy this paste it here and if this doesn't work we need to show an error so here accepts exception error equals there's some thing wrong please try again and then we just say return response error and then we pause in that error we created here and save so now we need to import this as well to the urls port stripe slash check session name check session and save but this will also need to be included up here save but if i now go back here refresh nothing will happen because we haven't called the check session yet so that is the next step now so you need to find a thank you page because that's going to be done there so plans thank you and then inside the mount that i need to call excels axios and then we use the url we just created which is this which points to the view we just created and to the back end we want to pass in a field called session id which we get from the url and session id that points to this parameter so now we send that to the back end then we get the response back like that exactconsole.log responses to see what we get from the server and when that's done i want to show a toast the plan was changed and this is success so it's nice and green and when that's done i want to update the team information like that so this dot store.commit.team this is the same thing it's done when you're signing in so we set the team id the name the plan the name max leads and max clients and if there are an error dot catch error now we want to show this as a toast as well like that and we can also show the console.log error oops errors we can show the information in the console but that should be okay and if you now refresh okay toast it's not imported so i need to find the page that has toast there just copy this go back to plans thank you okay save and then we can go back to the chrome you see here we get an error from the server invalid syntax on views.pi in the team folder okay what did i do there 125. okay i forgot to add a parenthesis here so save and now this looks okay have a now refresh but the plan was changed perfect as you can see here we also got this information about the team here great so when i go to team the plan changed to small team perfect so now the implementation of stripe is finished so now i can set the last task in the to-do list to done today we're going to make possible to cancel a plan show plan and date i'm exposed both to delete leads and clients and then fix something in the menu and the first task is to make a postpone to cancel a lead to do that we need a view in the theme app folder so if we just find team and then view pi then here we want to make a view to make it possible to cancel so we can add it here at api view this should be a post request and then def console plan request and the first thing we need here is the team so we can copy from up here and then we want to get the free plan from the database so we can assign this to the team plan free equals plan dot objects dot get name equals free so if you named your plan something else you need to fix that now you don't see that i have imported plan from the database and yes i have so then i can go below here and set team.plan equals plan free and team.plan status equals team dot plan canceled this is just so later i can check when we are going to update one time per month that if the plan is cancelled or what and then team.save and then we also need to call stripe to tell them to deactivate the next payment so try stripe.api key equals settings dot stripe secret kin and stripe dot sub subscription dot delete and then team dot stripe subscription id and this is one we got in the previous part and then we can say accept exception if there are any errors from stripe now say return response now we print an error to the user something went wrong please try again and then if the try did work now we can say serializer equals team serializer and i'm just post back the team to user so this should be lowercase and then return response and we pass in serializer dot data great so then to import this to the urls so just append it a pair somewhere and then just copy one of these replace upgrade with cancel replace and replace and save and then we need to implement this in the front end as well and i want this to be in the plans to the view page so if i find this page and then we can add an hr here and then div class column s12 button at click cancel plan and [Music] close button is dangerous it's red so you know that something shouldn't happen or it's something danger when you click it cancel plan close the button close the div now we need to create this method just add it here this should also be in a sync method so first you can copy this paste paste and replace with false and then we want to use excels to call the backend dot post api v1 teams cancel plan like that we don't need to pass in any data then we get a response back response oops response like this and then we get information about the team so i can copy this one and this one and this one paste it in there so now we set the theme based on the data we sent back and then we can change this to cancel so the plan was cancelled and now we redirected back to the team great so now everything there should be okay so i can save it go to the browser refresh so i can try to change plan cancel plan then i was sent back here and now the plan is free max clients five and max leads is also five perfect so done that is working and i guess that's the first task to done before i continue i just want to say thanks to my patreons if you two want to support me you will find a link to my patreon in the description below and then the next step now is to show the plan and date in the theme page to do that we need to change the serializer for the team because you need to have access to this field this field is called we are actually missing this field i thought that i added it in the previous part so then i need to add it now plan and date equals models dot date time field and this can be blank equals true and null equals true and save so now i need to stop the server and then i need to run the migration script so make migrations and migrate now we can run the server again good so now we have that field at least there so if i now go back to serializers and find the theme then i want to append it at the end here and save so now this should be available in the front end so if i now find themes.view there team at least not teams then i want to show it here so p strong plan and date strong and this should say theme dot plan and date and close the paragraph this is now empty and it should also not be showing when you're on the free plan because if you're on the free plan then you have no end date so on this paragraph you get v if then we can copy this not equals free save refresh and now this is gone perfect but i want to check that if i subscribe to the small team again that it is working to start this webhook listening again this should be the same as i had in the previous video but i can just double check that it's working find settings.pipe search for it yes it's still there so then i can try to pay yes still seems to be working sent back here and now go to team i have the plan and the date and this is one month from now perfect so then we have this data available done and then i need to make it possible to delete a team no delete a lead and a client so then i need a new view in the back end for the lead lead and then find views dot pi and then i want to use the api view at api view plus in post because this needs to be a post request and you see here i haven't imported this so you can go to the theme here and find it up there and then i go back to this.pie like that and i also need to import the the response so i can copy this as well like that so then i can scroll down to def delete lead request and and then i can have the lead id in the url so i don't have to pass in any data and then you first get the team just so that we know that the user is correct just to remove the self so we get requested user because when you are on a function based view you don't have access to yourself but you access your request this way and then we say lead equals team dot leads dot filter pk equals lead id so we get all the leads for this team and i'm going to filter it based on the primary key which we pass in in the url now we just say lead dot delete and we can then return response message delete was deleted and save so now we can import this into urls.pi in the lead app first we import it up here and then in the top we can say leads oops part leads delete lead and then hint and lead id now we pass in the name like this this actually has built-in personality for deleting a lead but since you're going to modify this and get the theme first and then do this then it's easier to just create a new view for this so we could just do this perform delete and then override it but it's easier to just do this so now the back end for deleting a lead is ready so if i now go to the lead dot view then i would add a delete button here so up here in the buttons we can create one more button at click delete lead clause button is danger delete then we need to copy this create this sync delete lead then we can copy all of the content from this get lead because it's kind of similar and then just want to convert this to a post and then we add delete lead there now we can say console.log response.data so we see what data we get back from the server and then we can redirect the user back to the leads page so just copy this redirect slash leads and save so then we should be able to test this i went to leads going to test company now we have the delete button there you can open up the inspector delete okay go to 404 error let's try to use this api one leads delete lead too okay i should not have the slash before leads of course so just refresh so the error is gone delete and now the lead was deleted and it's now gone from this list so it's still two because i have more in this list perfect so now we're able to delete leads great and then the next step is to make the same functionalities for client just want to set this to done so then it's the clients so if i just find views.pi pair in the leads then i can copy this function [Music] go up to vista pi in the leads app here i already have created or imported the the api view and the response so just need to rename a few things there delete client and clients client and the client was deleted and they should be client.id client.id and save so now you can go to urls and import it appear delete client then i can add it to the list here part client delete client and then we pass in the id and client id delete client and also just set the name delete client like that great so now the backend for deleting clients is finished we can go to the client dot view page just want to copy this from lead.review first now we can go to client just paste this rename it client rename this to client id copy paste it into there clients and delete client and then we want to redirect it back to dashboard slash clients then we need to create the delete button first we have the div class buttons so we get a little bit space between the different buttons button class button is danger let click delete client delete we can close the button close the div and save and we can test this we go to clients find client one edited delete redirected back here client is gone and we got the message the client was deleted perfect so then we can set that task as well to done and the problem with this is that you can see these buttons here but if i go and log out the buttons are still showing so that's a little bug we need to fix before we can deploy this project so if you find app.view scroll up sorry this is a component so in components layout navbar.view we'll still show this here so i can copy this down here where we check if we are authenticated but we need to remove this usually check that if we are authenticated then we want to show this so save then you can see here that the buttons is gone perfect and if i log in again now oops then you will see that the links are back perfect so then i can set this task so until done today we are going to deploy this project to a live server the first step is to install the necessary software on server so if i go to the command line i'll just log into it here this is a ubuntu 20.04 i created this with digitalocean before to try the digitalocean for free you can create a free account by signing up with the link you can find in the description below this way you will get hundred dollars in credit you can use for 60 days great so now that i have i am inside the server i can install the software we need but first i want to update everything and i do that by saying sudo apt-get update this will update all of the mirrors like this so the upgrade will be ready and then sudo apt-get upgrade and yes i want to update all of these packages great so now everything is updated and upgraded the next step then is to install the software we need so first i run this command sudo apt install python 3 pip pattern 3 dev lib pq dev postgresql postgresql contrib and nginx this is what you need for example for installing and using pip packages nginx which is the web server and the postgresql and postgresql contrib and simpler so now we have the database postgresql installed as well so hit enter i have already installed this as you can see but you will probably need to select yes to install this and then i want to install two more things sudo apt install search bot this is for getting ssl certificates and python 3 search bot and gen x this is so you can use nginx to get the certificates sorry there is typo forgotten t cert but great so now everything there is installed i can go to the to-do list and set the first task to done next step then is to create a database a postgresql database so you need to sign in to the postgresql user by saying sudo u postgres and then psql so now we are logged into postgresql and to create the database you say create database go nod crm and then semicolon hit enter so now we created the database next step is to create the user bus and create user gunners crm user the user name with password and then the password i want to use which is just gonna set them password and hit enter so i created a user which can use this database and then i need to change this user a little bit because i will need to set the default client encoding to utf-8 this is some configuration for using postgresql together with the django and then the same with this this is also a configuration to do with django and we also need to set the default time zone for the user to utc which is also connected to django and then i just want to run grant all privileges on database the one we created to this user so now this user has access to everything on this database great so then we can run backslash q to quit this user so now i've created the database as well so you can go to the command line that this task to done as well then i want to install virtual env using pip so go back to command lines and sudo h pip 3 install upgrade pip just want to make sure that we have the newest version of pip installed great and then sudo h pip 3 install virtual enviem and now we have virtual environment installed on our server nice done and then i want to create a group and user for the project i can begin by creating a folder mk pair dashbeam slash web apps slash gunnard crm this will be the home folder for the user and also the project you can go there like that then i want to create a group called web apps so just draw pseudo group ad to the system and the name is web apps okay already had this group that you need to edit yourself and then to create the user for the project is a sudo user add system and then group id which to group the user should belong to set the shell and then the home which is slash web apps slash gonna rcrm and then the username and this user is the one who usually access to this folder and writes to change files and similar nice so then we can set the task as well to done and then we can create the environment where the project should live so virtual env environment 382 which is the pattern version i'm running and then we activate it by saying source environment bin activate i can go into that folder as well because this is where i want the django project to be placed and then when that is done i need to install the same packages we have locally on the live server and through that i can go here you can see this is activated locally on except freeze and then i got a very long list of packages we have installed locally so just copy the contents of that and now it's a vi for creating a new file or eq.txt or q just stands for requirements and then i for insert command v for pasting we can save and quit write quit now we install this button pip install dash r to use the requirements field now we select it and hit enter now we will install the same packages here as we have locally so that we know that the server will run the same way great and then i want to install one more packages for the for the postgresql server pip install psycho pg2 dash binary and this needs to be installed in order for django to use postgresql perfect so then the environment is created and set up so you can set this to us to done next step now is to get the django code from get so if i go to the chrome and then go to my github account then i find the project error and conor crm and then i go into i can actually just copy all of this and just remove a little bit so then here as i get clone and paste the url so now i have the project here on our crm but i don't want it to be in there so i need to go into that folder click on our crm i want to move mv i've got another crm chango at one folder so now i have this here and i can rm fr conor crm so now i just have the the jungle folder here perfect so now that we have the code we can go to the next task which will be copy the settings file and change that a little bit so go into this one and let me say cp for copy on our crm django settings conor crm settings but rename this to prod so we want to separate settings file for the production now we can edit it conor crm settings prod dot pi and you should update all of these but i'm not going to use or test the stripe live but you just need to update the keys for the live environment you have in stripe the front end these two also needs to be changed it should be to the website your url and also this one and then inside the allowed hosts i need to add conor crm.code with stein.com which is the url for my server and api conr crm dot code with stein.com and i can also append these urls here https because i'm going to need going to use that and https api.comcrm.com like that and then i also need to update the database so i need to scroll down to find this because here we're not going to use sqlite3 here we want to set up the database so here we select postgres ql psycopg2 as the engine and then the name this is the database name which is gunnar crm and then the user which is gunnar crm user and then password which is gonna crm password at least this is what i set up when i created the postgresql database and then host this local host and port oops can just be empty great so now everything here should be changed and this should be ready for production i just want to mention that there is a variable called debug this also needs to be set to false i just want it to be on true until we know that everything is okay great so now we have done this and then we can install and set up g unicorn g-unicorn is the application server for hosting django g-unicorn is not supposed to handle for example media files we need to use nginx for doing this but nginx can't handle django so we need both of these servers but first we can install g unicorn pip install g unicorn hit enter great i can go upon folder so i'm here in the environment folder and then i need to create a new file vi bin g unicorn underscore start so this will be the starting script for the project and this will run the server activate environment and similar so first you just add this to the file since it's a shell script and then we set a few variables first this is just the name for the project it doesn't really matter it's just nice to know which project is running and then the django directory slash web apps conor crm and then environment folder and rcrm django this socket file will be automatically created when we start this script then the user to execute this script this is the user recorder with the user edit command and not the postgresql user then the group just belongs to and then number of workers this is the number of cpus you have on your server multiply with two plus one so i have one cpu multiply with two that is two and then add one then it will be three and then which settings file to use and that is pointing to this project up here and then settings prod which is the settings file i just created and then which wsgi module to use this again points to the project and a file called wsi in that folder not always we have seen it in this project but you can go and look at it and see what it has inside and then the timeout for this if something is wrong and then a little bit of command to use first we go into the django directory and then we activate the environment and then we set this environment variable this is based on this and also the python path then we tell it which where the run director is and then we test if this exists and if not it will be created so if this doesn't exist it will be created now and then we just execute it by running g unicorn with this wsgr module setting the name the workers and everything from up here and we can save and quit this and then we just need to make this file the ball by saying chmod plus x bin to unicorn start nice and to make sure that this script is running at all time we need to use something called supervisor before i go there i just want to set this task to done then we can start that task first you need to install supervisor by saying sudo apt install supervisor great i already installed this so now we can go to cd etc supervisor ctl oops supervisor slash conf now we want to create a new file vi conr crm django.com and then first we set the name of this program and then we set the url to the g-unicorn script we just created and then which user to execute this which is also gunner crm and then we tell it where to load things if there are errors or just accessing this web server and that we want to redirect the stand standard errors yes and then we just set some environment variables so now we can save this and quit now we just need to tell supervisor to activate this by saying supervisor ctl re-read to check that everything is okay okay this log doesn't exist and create that folder okay there and then touch just to touch this as an empty file like that now we can reread it's available perfect let me say update added to the process if i now run status you'll see that it's starting and now it's running nice so now the script is running in the background and if something crash or similar this will automatically start again or at least try to start again so then we can set this task to done and then the next step now is to get ssl certificate so to do that we need to run search.script and then we say sudo search bot dash crm dot code with stein.com hit enter and now just checking that this domain is pointing to my server and similar and now it created a new script or a file here perfect and then i need to create one more for api dot like that so we can have it should be both for the api and the front end nice so now we have that as well then we need to configure nginx so cd edc nginx sites available and then we create a new file by saying vi api click on our crm put code with stein.com and then first we create something called gunnar crm app server this will point to the socket file we saw in the general storage script so this sets up the server we can point to then we want to listen to port 80 check if you use not http so it can redirect you to https and then we want one more server for listen443 ssl so all we can also listen to https traffic then server name is also api on our crm like that then we set the client max body size and we also set up the access log an error log which is in the same folder as the g unicorn log file then we set up the ssl certificate this points to the url i just highlighted when we got the certificate for the api and then the setup some protocols and similar i will add all of these files in the github repository so you can see them there or copy them if you want to do that and then if you go to slash static on the api you will be pointed to this folder and get the files inside there if there are any and the same with media and if you go to just slash or the main site itself it will set up a proxy header and it will point to everything if it's not a file name it will point up to the gunner app server which you created on the top of this file now we can save and quit this then we can go to sites enabled here and then we set up a symbolic link back to the file we just created alan s sites available api conr crm like that so now this points to here where we are right now so then we can restart nginx service nginx restart okay there is a problem with the configuration just copy and paste and run this so we can see what's wrong unknown directive server name okay there's something wrong with that file okay it was supposed to be server underscore name like that i can try to run the restart again and now now error came so now it should be running but i think we will get an error if i go to this site yes i get a bad gateway and i think it's because of some rights for the folder so if i go to slash web slash gunner crm you'll see that root is opening everything in there and i want to change this by saying ch own dash r go on our crm call on web apps and then that folder and i use dash or since it's recursive so take all files inside there and i can restart everything with the supervisor by saying supervisor ctl restart conor django okay gunner crm django maybe the name was yes now it's stopped and started again i can also restart ng next just to make sure that it's okay refresh and now we see the front page of our api so then i just want to change one more thing in here environment and generic no conor on our settings prod and that is the debug this needs to be set to false so all other users can't see your error errors and similar so now we can restart the supervisor again so every time you make a change to django need you need to change or restart supervisor if i refresh now it's just not found because there are no page to try go to admin for example now i'll go to admin administration perfect and then the last step i want to do now before we fix the front end is to initialize the database because you haven't done that yet here and to do that we need to go in to the folder like that and then if i say cat manage.pi you will see that this actually tries to use this file but do you want to use the settings prod so python manager pi make migrations settings and then just go to rcrm.settings prod okay no changes detected that's okay because there are no changes so then we just need to run the migrate script so now it recreates all of these tables in the postgresql database server you can restart again just to make sure that everything is okay perfect and then i can go back to the to-do list and set this to done and then i want to build the view project locally and send it to the server so instead of using getter i want to send it so go into gun rcrm view and run npm run build and now i should get a new folder in here called dist and this contains all of the built files or compiled files we want to send to the server through that you say sap for secure copy dash r because i want to send a whole folder notice that the dist folder and i want to send this to root which is the user connor crm dot code with stein.com i can just paste it or place it at the root folder and then the password for this server and that's it so now i sent all of the files there so if i go here now slash web slash gunner this is where i want this to be placed so if i move it now mv slash root dist this is where it was placed when i when i sent it using this command i wanted to be placed here so now i have a dist folder and environment folder perfect so then i just need to set up a new nginx config to point to this dist folder so cd etc engineering sites available and vi conor conor crm.code with stein.com and first i set up one server for listening to http which will return or redirect you to https and then i do the same thing as with the api i listen to 443 set up the server name the current max body size and then error log and access log and also the certificate then i set up the default charge set and where the root folder is and this was just supposed to be slash dist web slash gun rcrm slash test and then inside this folder this server should look for index.html or index.htm and then set the one location because if you go to the this folder and this should be the root folder for the project like that so here again you try to find this inside there and that was the configuration for view now we can go into sites enabled set up a new symbolic link sites available on our crm there now we have this here as well and we can try to restart x create no errors then i can copy this address try to go here and yes now i see the front page of gunner crm perfect nice so now we have deployed our project to live server hope you enjoyed the series and if you did please click like below if you have any questions about this process for deploying feel free to leave a comment below also and answer as soon as i can see you in the next video
Info
Channel: Code With Stein
Views: 2,313
Rating: undefined out of 5
Keywords: code with stein, django, learn django, django tutorial, django and vue, django full course, django rest framework course, django crm
Id: u2RJXTtCn2Y
Channel Id: undefined
Length: 365min 14sec (21914 seconds)
Published: Thu Nov 11 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.