E-commerce Website With Django and Vue Tutorial (Django Rest Framework)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
you're about to learn how to code an e-commerce website using django and vue that means you'll be using python on the backend and javascript on the front end you just need to know a basic understanding of these technologies to follow along this course was created by code with stein he's created a bunch of great courses on his own channel and we wanted to bring him to a larger audience hi in this video we're going to build the e-commerce website using django and vue i'm going to use django rest framework to build the api and the back end and then i'm going to use vue.js to build a separate front end which we're going to use to connect to the backend using axios to handle the payments i'm going to use something called stripe this course will assume that you have basic knowledge of both view and django but i will still try to explain everything as good as i can so hopefully you should be able to follow along anyway let me show a little demo of what we are building so it's easier for you to understand and follow along here you can see the project we are going to build we have a simple menu with the search the categories login button and the cart button and have a simple header which is uh welcomes you to the page this is a jacket store you have the latest products and a simple footer i go into one of the categories you'll see the products from this category and if i click view details you will see the full version of it with a bigger image title and a description you also have the price here and the possibility to add to cart and if i click add to cart you'll see a little pop-up down here which says that the product was added to the cart if i now go to the cart we have the possibility to change the quantity and you can also remove them from here if you want to like that and then the price updates here and also down here and if i now try to proceed to checkout just log in with my username code with stein put my password and then i headed to the checkout page here i need to fill out contact information card number etc and then we click paid stripe and when send back to the page afterwards to a simple success page and if i go to my account here i would have a list of my orders if i had any i don't have any in this version of this jacket store right now and i also have possibility to log out so that's basically the product we are going to build i hope it looks really interesting to follow along with i'm going to build everything from scratch and step by step and when we finish we're going to deploy this project to a live server on digitalocean but now it's time to get started with the coding here i have the to-do list you are going to go through in this video it's quite long but we're just going to start at the top and work our way down first i'm going to install a setup django and everything we need there i have a folder here jackets would be which will be the root folder for all of this project view django and everything we need okay inside this folder i want to create something called an environment it's a virtual environment and every python package we install here will only be for this environment so when we are deploying this project later it will it will be much easier to have the same environment locally and in production and to create this just a virtual env and an environment eight or three eight two which is the python version i'm running and hit enter so now i have now i have it there on the computer we just click ls you'll see here the environment folder and then i need to activate it so we can install some packages and to do this i said source environment then activate as you can see here we have prepared the no environment 382 this means that if i now use pip to install something it will only be installed inside this environment and if you don't have virtual environment you can install it by just writing pip install virtual env in one word like this pip install virtual env i already have it installed but you obviously need to install it if you don't have it it might be a little bit overwhelming with all this environment and everything you're going to install right now but we'll come back to much of this later in this video so then it hopefully will make much more sense when we go through them multiple times so the first thing we're going to install now is django so just pip install django this will install the latest stable version of django and also a few dependencies that django has latest version of django is currently three one seven next we are going to install the django rest framework to this you just say pip install django rest framework this is what you're using to create the api in the back end and hit enter this also has a few dependencies and then we can install django dash course dash headers this will help us with security so everything between api and backend will be working securely and then we are going to install joser this will also help us with authentication users and similar juicer adds some a few endpoints to the api so it's easy to create users log in get a token for authentication and similar so just hit enter and this also installs a few dependencies and then we can install pillow this will help us with resize images and similar this is a python image library but pillow is a different version of it but it's much better and really easy to use and the last thing you're going to install in the back end is a stripe so just right click install strip so now everything in the back end is installed and we can start configuring it we just need to create a new django project and to create the new django project you say django admin start project and then the name i just want to call it jacket underscore django so i know it's the django part of this project and if i go into it check it's underscore django have a new folder in there and a file managed pi is used to run administrative tasks like initialize the database create super users and similar and inside the jackets django i can open it here so it's easier to see i have a initial spine that just means that python should handle this as a package asgi and wsgi are entry points for the web server settings to spy are globally configuration for the whole project and urls.pi is kind of like a table of contents of all the pages in the backend so i will come back to all of these later so we don't have to think too much about it yet okay and then we need to tell django about those packages we installed so if you're going to set install pi oops we have a list of installed apps there are a few that comes from django these ones but we want to add more to this first we had the rest framework just so now django knows that we are going to use it as well and then the next is restframework.org token because we're going to use what tokens for the authentication and course headers we installed and also joser so now we have uh said to django that we're going to use all of those and then the next thing we're going to use do the next thing we're going to do is to configure the course headers so below here add two lines course allowed origins this will be the address to the front and later you need to change this to the live server address or if you use a different address for the front end than i am and we also need to change the middleware middleware is the coded and that goes in the back end of django so above it's important it is above common middleware you say courseheaders.middlewear.course middleware so it's just that the django u goes through this code before it goes to the next part of the django code and that's it for the configuration so now we have done everything for the security in the backend for now then the last thing we're going to do is to go to urls just to remove this big comment here and i'm going to include the api fonts i told you about for joe sir so we are ready to create users but you need to import one more thing from django.urls and this includes so you can include pots from that project so first pod api slash v1 we include jose.urls and the same bot here and includejoser.urls.token so now we have everything we need in the back end this has added a lot of cool functionalities and now we can create users you can get authentication tokens and similar from the front and it looks a little bit like magic because now we get a lot of functionality without doing a lot but you will probably understand a lot more when you have used it a little bit so you can just save this file for now and then i want to do one more thing here in the backend and that is to initialize the database and to do that i said python managed to apply make migrations that's just to create the migrations files and then to run them i say python mentioned by migrate so now we have a new database with all of these tables so to test that everything is working we can also create a super user we can log into the admin interface that django comes built within python management by create super user oops super user and then i want the username to be admin admin jackets.com and then a password hit enter and now the superuser created successfully perfect and then to log into the admin interface we can run the development server that django comes with by saying python mentioned by run server this will store the development server at this address just copy this address go to chrome and it's not found because these are the only urls that are available but if i go to slash admin i can log in with the admin account i just created and everything here seems to be working we have the auth tokens but there are none yet of course and if i go to users i will see the user i created a new search is signed in and using the front end will appear here as well so that should be it for the back and for now now i can set the first task here to done next step now is to install a setup view and i just want to open up a new terminal just for view so cd documents and jackets that should be the correct folder okay and to create a new view project you need to install view cli first to install it just say npm install g at view cli this will install the newest version of view on your computer and when and just hit enter but i already installed it i'm not going to go through it right now so since i'm right here now i can create a new project by saying view create and then check it oops check view should be the name of the project and i want to manually select which features we're going to use we won't be able to transcribe the code real javascript i'm going to use the router the view x css preprocessors i can just remove the linter and then i can hit enter going to select 3.x preview and i'm going to use history mode for the router yes and i want to use dart says and i can store this in dedicated config files and i don't need to save this for later no so now this will install now create a new gnoview project and install the dependencies that view has great so now i can go into it cd jackets view oops check it view and i need two packages or libraries here as well to install them i can just say npm install axios this is a library you're going to use to talk to the back end and npm install bulma this is a css framework i'm going to use i don't have to think too much about the styling and similar for this project because we're here to learn vue and django so now everything there is installed i go back to visual studio code just look at the files here we have something called node modules which is the the packages we have installed public is the index.html which is the file we're going to serve and we have a few other config files and in the source we have the main.js which creates the view app app.view is kind of like the wrapper around all of the code views are the different pages store is view x which is a global state management for the whole app router is almost like the urls does pi in the django project it's all of the pages in the project components are small or large reusable parts of code we're going to use as well and assets will be images and similar i know it's a little bit much information right now but when we just only start adding code to each of them you'll probably understand what each of them do when you just done it a couple of times and if you want to use bootstrap instead of bulma you are free to do so but i'm not going to do that and it will be a little bit different but it's up to you what you want to do and if you want to test the view everything is okay we can say npm run serve so this will start a development server and this is the address we added in the backend just in the settings to spy so if i now go open up a new tab hit enter you'll see everything you'll see the front page of the view here and switch route so we see that everything is working perfect so now i can go back to the to-do list and set this task to done next step now is to include font also i want to use some icons around different places in the page so it's very easy to implement i just go into public and into the index.html and then below the title here i just paste this one linked real stylesheet and then the link to the cdn which holds version 550 and two of of uh font awesome and save so this shouldn't have done anything with the front end so you can just go back here again as that this task clip done next now is i want to do some changes to the base template i want the menu and i want to remove all of this which doesn't have anything with our ecommerce website to do so if i just go back to app.view make this a little bit smaller and i can remove the contents here and i want to import my hair and to do that i just say at import dot slash node modules slash bulma i think that's everything i need for refresh now yes it looks like i have gotten the styling and i can remove this nav bar i want to create a div id wrapper around all of the content just to have one element in this template because that's required by view then i want to create a nav with class navbar is dark this is bulma clauses which will give a menu on the top with the dark theme close the nav just go in here said div class nav bar brand this will be the logo and then to show the jackets logo there i create a router link to just slash which is the front page and give it a class of nav bar item and then i just a strong jacket and close the strong and also close the router link down here i want to create the possibility to have a hamburger menu icon when you are on small devices so we just say a close nav war burger area label expanded false data target nav bar menu network menu will be the menu that shows when we click this icon and then add three of these which are three stripes in the burger then i can close the nav bar brand and then add a new div class navbar menu which you can see this are linked like that and one more div class nav bar and because i want the menu to be on one side of the page and the logo on the other page now the other side of the menu and here i want to add the two categories we're going to have summer and winter it's just router link to slash winter class navbar item and then the label we're going to show in the menu and then the button for the card is a little bit more complicated first we need to add a div close nav bar item and then a div close buttons because we're going to have two buttons and to get space between them we add this buttons clause and then the login button is just router link to slash log in button a slide to have a light grey button with the label log in and the same with the chord it's just slash chord and it's success it's green is a little bit more pretty or inviting to click on and here i want to show a shopping cart icon spam clause icon and i close fos fa shopping cards and then spam spam card and close the spam and close the router link close the buttons and close the nav bar item and then to get a little bit space below the menu and around the content we add around this router view a section clause section the router view is where all of the content is placed and then below there we have a footer class footer and then just simple paragraph showing copyright 2021 and class has text centered footer and save so if i now go here you'll see that we have this menu and everything from this logo and down here is inside that router view so if i now go to slash about which is a page that exists this is the router view content great so i can also just go to views and into home.view and clean it up a little bit and remove this one just say home remove the import of the hello world because we're not going to use it right now save if i go back now i just say home there perfect so now i think i can go back here and set this task to done because now the front end is finished for now and i can go back to the back end and start working with the products we're going to use in this project okay and if for now we just try to test this on a mobile device you'll see that we have this hamburger but nothing happens once we click it so we're going to need to implement some view js to fix this so if i just scroll down here create a new script and create a data return this is that object and i want one property here show mobile set the default to false because we don't want to show the mobile when we open the page before we click the button and to make it possible to click it we can go up here and find the button and i add here at click so when we click this we call the function or the code in here and just say show mobile menu equals not show mobile menu so if it's true it will be false and if it's false it will be true so now we just need to append a clause to this one it's true and to do that i just go at the end here paste a little bit of code v bind so we bind the attribute class to show is active if the show mobile menu is true so if you just save this now this is a view directive if you wanted to know what this is called just refresh and if i click here now you will see the menu go up and down perfect and then i can go back to the to-do list and set this task to done next step now is to go to the backend i created django app we're going to create database models to have information about the products and the categories and to create the django app we just stop the server down here and say python managed pi start app and then the name which would be project and hit enter so now if i scroll up there should be a new folder there called product with the migrations folder the init.pi admin which will we use to register the models we create with the admin interface and apps which is information or config about just this app models.pi is where we describe to the database what types of information we're going to use and store tests or python tests and view those buyers where we get information from the database and present it to the front end so first we can go into models.pi and just remove this command okay so first i want to begin with the category model to create a new model with just a class category and pause in models.model i want one field called name which is a chore field with a max length of 255 this will be the name of the category and then i want the slug which is the address version of the name models.slug field and i want to order the categories by name in the backend at least and to do that you need to add something called class meta which is options for the model ordering create a tuple name and this is a template you need to add a comma there so it's iterable for the backend and i also want the string representation of this object because if we now add the category and see it in the back end we'll only see object blah blah blah so we want to show the name instead to do that we said def underscore underscore str underscore underscore was it himself say return self.name so that's much easier to understand what type of object it is and i need to create one more function so we can get the url for the category so it's easier to use in front and later this can this function is called get absolute url and to use it we just say return f so we format it with slash and inside there it pass in the slug which is the address of the category and save next step now is to use the migration script again to update the database but to do that we need to tell django that this app exists and to do that we need to go into install apps and at the top here i can say product so you need to you go information inform django about the app and not the model so if i now go down here i said python managed to apply make migrations you'll see that you want to create a new model called category and then we need to run python managed by migrate to actually create it in the database now the product cat no the product model will be a little bit more complicated first i need to import bytes io from io because we're going to handle images here and resizing and then i want to import peel which is pillow installed or import image from that library and from django.cod.files i want to import files so it's easier to create thumbnails and similar now we can go down here and start working on the model clause product models dot model the first field i want here is a reference to the category i want to use something called a foreign key which is index in the database or a relation key so first you just pause in category and set the related name so when on a category it's easier to get all the products by just saying category.product.all and if you delete one of the categories we also delete all of the products connected to it then i can just copy the name because i want to use that and also the slug then i want one field for the description this is set to blank equals true and null equals true so it can be empty if you don't want descriptions for a certain product then add a field for the price which is a decimal field set max digit to six and decimal places to two this might be different in your country than here in norway and then i want one field called image which is image field we upload this to a folder called uploads i'll show you where we're going to place this soon set also these two blank and no liquids true so we don't have to have image on all of the products and then one field called thumbnail we're going to generate the terminal based on image very soon i'll show you how we do that and the last field is the date time field with autumn now add set to true so when we create a new product in the backend it would automatically fill the date time field so we know when it was added to the database then i can copy these two i can actually copy all three of these paste them down here but we don't want to order this by name we want to order by the newest so copy minus date edit so we get them in descending order the string can also be self.name but here i also need to append self oops at the curly braces self.category.slug so now we get this log based on this category field and here we also need a few more get no functions we need one for f get image self here we check if we have the image in that field and if you do we return the whole address so it's easier to use in the front end and then we just say self.image.url if not we can just return an empty string and then we want the similar for the thumbnail get thumbnail if self dot thumbnail now we can just return the url to the thumbnail else and we first need to check if we have the image because then we need to generate the thumbnail and if you have it we can say self.thumbnail which refers to this field then we call a function called make thumbnail and pass in the image we have for this and when that's done we say self.save so it's saved in the backend or in the database and then we can return the address here but if the product doesn't have an image we just need to return empty string and now the last thing for this model is to create the make thumbnail so def make thumbnail self and image and we also need to set the default size to 300 times 200 pixels wide and then we're going to use the image we imported at the top here to create a new object based on this image just convert it to rgb so we are certain that everything is okay with the picture and we just say m.thumbnail and pause in the size we get up here so thumbnail is a in a built-in function in image there is a thumb i o and use the byte style we imported at the top and we save the image within this information as a jpeg and quality is just at 85 because this is just a very small thumbnail and then we need to create a thumbnail using the file we imported from django core files and we pass in image.name and now we just return thumb nail and save so now we will set the thumbnail to the image or the terminal generated and save it and return so now we can update the database again run the make migration script create product model and migrate great so now everything there is working perfect so now i can run the server again so i have it running in the background and i can go back here and set this task to done and sorry i just forgot one thing i need to fix the uploads folder so if i go to settings.pi we just need to tell django where to put the files first is that media url to this this will be appended to the end of the address of the server and the media root is where located on the server we're going to upload the images so just paste there slash media so now we can save we don't have any errors and everything looks okay perfect and then to use the the media in the front end we just need to go to urls and do a little change here as well so first we need to import the possibility to use the settings here in the urls file and we need to use a function called static from urls and at the end of the url patterns we add static use the media url and just tell django where the document root is this won't be used when they're going to use live because they will use a different server so we are still going to see some progress in the front end so it will be a little bit more exciting but we can now continue to the next task which is create a serializers and views for the project over products the serializer is where we get the information from the database and turn it into json so we can use it in the front end and to create the serializer we just scroll up and find the product app create a new file serializers.pi first we import serializers from the django rest framework now we can import the category and project model since we are inside inside the same folder as mods.pi we can just say those models and python will fix this for us then we create the product serializer and posin serializer dot model serializer to configure this we use the class meta just like the models and we say model equals product because we want to use the product model to get information and then i just configure what fields we're going to use in the front-end fields this is tuple and then we want the id the name to get absolute url function so we get it directly here the description the price get image and get thumbnail so if you have an image and when we call this for the first time the in terminals will be generated for us so this can be saved next we need to create a view set so we can actually tell django what we are going to put in or get from that model so from dot serializers import product serializer and i also need to import a few things from the rest framework i'm going to import api view and import response from rest framework dot response and i need to import a product from models and then i want to create a view set for getting the latest products which are going to show on the front page so create a new clause called late test products list and pausing api view this is generic views built inside the django rest framework helping us do all of this magic then i want to create a new function called get so we can override that functionality and do a little bit changes and we get the product from the database by saying products equals product product.objects.all and then we just want the first four or the latest products and then to convert this using the product serializer is a serializer equal product serializer plus in the products and say man equals three because we have more than one object and then we just return response and position serializer.data and we want a separate urls file inside here to clip keep things still tidy as possible from django.urls import port and include and from dot views import latest product list url patterns so this is just the same as the other file it's just more clean to have it a separate file for each of the models know each of the each of the django apps actually i can say from product import views so it's a little bit easier to separate them later and then put late latest products views dot latest products list as view and save and then we just need to import this to the other url spy file so at the bottom here we say part api slash b1 include product dot urls and save so everything still seems to be okay here i just go to the browser api b1 and i don't get anything there but if i go to latest products it's empty because they don't have any products in the back end yet so if you want to create a few products we need to go back to visual studio code and inside the admin.pi file in the products app you need to say from dot models import category and product and admin.site register category and admin dot site register product so if you now go back to the admin interface front page here you'll see that these two appeared here perfect so we can now add summer summer with lower cases and winter winter so now we have this hair great and we can create a few products summer brown leather brown leather the desk 199. and just select image just go in here select that one open save so now we have one product there you can create one in the winter as well warm jacket warm check it the desk for this product 2.99 and select the winter image and save and if i now go to the latest hair refresh you'll see that we get information about this product so we get the name the url the description price and the link to the images if i open this in a new tab you'll see that we can see the full size and also the thumbnail great so now i can go to the tool list again as a test task to done so now we can finally do some work on the front and again we're going to show the latest products on the front page so if i just go to home.view first i just paste the code to show the header with the welcome to check that information and then below here i want to list the products the first i created deep class column is multiline so i can have the title and also the products next to each other below there so then i paste a little bit more code the plus column is 12 it fills out the screen h2 which is size 2 which is medium sized and is centered so the latest product stays on the center of the screen then i create a product and for each of these columns i want to look through the list of products we are going to get very soon to do that we say v4 product in latest products oops products and you see now here i've got an error this is because django no view expects that each of these elements are unique so you need to find an attribute to the product id the point key product dot id so for every iteration we bind the data key to the id which should be unique for each product just close that one div class box so we get a little bit shadow around product and at the top i want the image figure class image and before so we get a little bit space below the image down to the text and to insert the image we just say mv bind src product dot get thumbnail and this is the whole url to the image we could use a shortcut to bind it by just saying colon src if we wanted to we can close the figure then we want to show a little title h3 clause is size 4 and then we show the name by using the curly brackets just like in django as a product dot name below the name i want to show the price this is just a little b with each size 6 has text gray and then the dollar sign product.price and then the last thing i want to add a button to review details but since we don't have that yet we can just write view details close that one if i save now and go back first of all i get an error because i forgot to close one of the divs but it won't work because we haven't created a function to get the information from the backend so this time we need to use excels so first and down in the script i say import xios from excels and then below there is a data because you need a new object return and latest product and create an empty list column there it's low here i want to go into one of the life cycles hooks of view called mounted so when the this page is finished we call this code and that is this dot get latest products and then we create that method below here in a new object methods like that and in here we call excels xcos dot get api slash v1 slash latest products and when that's done we get a response back from the server and then we can just this dot latest product equals response dot data because there's a list of objects so it's very easy to use like this and if you get any errors we can just show them in the console for now you can fix this later in the video and a little thing too i want to do is to create a simple style object at the bottom because on the image i want to remove the spacing around it so it looks a little bit more pretty it's just margin top minus 125 same with the left and the right so if we go back now it still won't work because we try to just go to slash api so here we could write the whole address to the server but i want this to work by default to do that i need to go into main.js as you can see here we haven't imported excels anyway so we need to import it here and tell you to use it so import excels from xcos and then below here i say excels.defaults base url and then the address to the server which you have running down here and then after router i say excels and save so everything should be working and if i just go back here now we have already gotten the latest products from the server perfect so now i can go to the to-do list one more time and said done next now we're going to make it possible to click view details and go in to the detail page of a product okay and the first thing you need to do done is to create a new view set for the detail of the of the product so go back to views.pi and then we create a new clause product detail and also going to use the api view here but instead of the get function we're going to use a function called get object and here we're going to pass in the categories log and also the product slug here we need to check if the object exists pressing try and then we say return product.object.filter so we filter every product that is inside a category and then we get the slug or the product based on the products like we get up here and if it doesn't exist we will get an exception so accept product that does not exist this is the correct exception for this and then we want to erase the http 404 error and to use the 404 error we need to import it you can remove this render and just from django.http import http 404. so this is now a function and then we want to override the get parameter or function like we did here so def get get the request pass in the slugs and format set to none and then we get the product the same product equal self.get object which calls this function and pass in the slugs so we don't have to reuse this every time and we still want to use the product serializer so we get all of these fields for the full version as well then we can just say return response and pass in the serializer just like up here and save next we need to go into the urls file and below here we create one more path products slug it is a field or string and here django nara requires that you pass in a slug which we call category slug and once local products log these are references to these two and then we just say we're going to use views dot product detail i'm going to render it as a view and save so now we have a view for showing the product next is to create a view page it's not a view like in django view but viewers in view so if you just go down here and into views create a new file called product dot view in here we always begin with empty template and empty script name can be set to product and we can say data return can just be empty for now and we can import excels from excels because you know we want to use this first i like to create one div class element page product just don't know which page we are on and then create a div class column it's multi-line and then to the left on the screen we have a div class s9 which is almost a whole width to show the image the title and the description first we showed image just like in the list of protests but here we use mb6 we get even more space below and we bind src attributes to project get image instead of get thumbnail and below here i want to show the title so h1 clause title type and add this clause we get it very big and pass in project.name and below there i want to show the description now you can close this column create one more div close column oops s3 close that div first you just want to show a subtitle with information about the product then i want to show the price and i prefix it with a dollar sign and then i add the button and input field for the add to cart functionality this is a has add-ons which means that the button and input value will be into each other i use input type number because i expect to get the number in the back end and class input so it gets pretty styling and the minimum i allow is one and then i bind the model this field to a data object called quantity so if i now go down here inside data i can say quantity one sorry not these quotes like that so this is default now to one and it can't go below one and then below there i create a new clause control and have simple button add to cart i will fix this later in this video and then to get the product from the server we need to use axios and he's use the mounted function again so mounted this dot get project oops methods get products like that and the first thing i want here is to get the categories log from the url we are on and i also want to get the products like before i do anything more here i just want to import this page into the router so we can visit it and see that everything is working and i want to add one more product here which can be an object just so things here will work and not crash the site if i now go to router you see here that you have the home page and the about page but we now want to import the product page we just created so import project from dot slash views slash project dot view then we want to append it at the bottom here because this has the same url structure as a project but we want to use dynamic routes and that's best to have at the bottom so create a new object this part and here is a slash colon category slug this is the name of the parameter slash colon product slog so just easier to separate the slopes from each other name project and the component we're going to use is product which we imported here a component and page is almost the same thing and save so everything here seems to be okay so for now go to the home page to replace the view details label with the button like that now we have a router link and we bind it to attribute called to and here we pass in the product that get absolute url which we get from the backend the button is dark and has empty force a little bit space above the button so if we save this now go back you see this turn into button and at the bottom of the left screen you will see winter slash warm jacket if i click it get an error because this does get product is not a function okay if i go back to product.view this should be get product just refresh okay so there's no errors perfect if you see these warnings here i'm going to fix this later it's just because the winter the category and login similar doesn't exist yet so now we need to continue this and get the product excels dot get slash api v1 and to get the products we now say products then we want to pass in the cat node products log but first the category slug dollar sign curly bracket like that slash dollar sign curly bracket and this but this formatting doesn't work if you use this regular quotes so we need to replace it with this like that so now we get the correct url and then we will get the new response back from the server and then we can just say this dot product equals response dot data and if there are any errors you just console log errors you can show it in the console if you want to know what error is so if we save now go back here refresh okay there's an error dot done is not defined sorry i forgot to add the dot refresh and now we got information from the servers now we have the image title description and also the price if i go back to the front page now click this product instead it everything here has changed perfect so now i can set this to done this to dawn and this to done great done next now is to set up the view x or state management we need this to make it possible to add things to the cart for authentication and a lot of other things so if you now go back and find store index.js i have already created a store this comes default from view state is the variables or informations mutations is synchronous mutation students variables because you can't just change them directly actions will be asynchronous function to change it modules i'm not quite sure so inside here we create a new couple of new products so in here we create a new so in here we created a couple of new properties first we create a new object called cart and inside there we have one list called items and then we have is authenticator we can just set it to false so it's done and same with the token this will be used later when we add login and it's loading set defaults because we want to show a loading bar when we're going between products anything into the cards in my cart and similar i can just save this and i can set this to done because that's actually setting up the store like that so now we need to make it possible to add things to the cart and then we need to add some functionality to view x and we do that inside the mutations first i want to create a function called initialize store this is so we can store things in the local storage of the webs of the browser first we check if the local storage exists with an item called cart and if it doesn't we just create it and if we get it from the local storage we can state.cart which is this json.parse and then we get the object from the local storage but if it doesn't exist we need to create it and then we say local storage dot set item cart which is the name of the object and then we stringify this object and then one more add to cart state and here we want to pass in the item we want to add to the cart first we create a new variable called exists so here we check if the item we are trying to add to record exists in the chord from before so we add a test here if exists that line so if it's larger than zero then we know that item is already in the course so we get the first object in this list since it's already in a list i just do it like this as a quantity parse end get the quantity and add the quantity we try to add from the this form here so this is a 10 there it's increased by 10 but if it's not in the card you need to add it to the cart and to do that we just state.court.items to push the item and so all of the information we get will just be pushed right into the cart and then we say local storage set item cart and then we stringify the whole object so the next time if you just refresh the browser now everything will be stored to the next time perfect so then i can set this to done initialize the store in app.view so then i need to go back to app.view because the first time or yes when we go into the page we want to make sure that the store and cart is existing so in here i created one object called cart so i have it available in this template because we're going to use it up in the menu and just like we have a hook called mounted we also have something called before create so before this is created we want to initialize the store and to initialize the store we say this dot store dot commit initialize store commit is used to call the actions we have here no the mutations not the actions so if i just go back here now we now initialize the store and we can create or and we can close the before create so then i can set this to done and then i just want to show the card length up in the menu so if i go back to app.view again and scroll up here after the chord we said that two parenthesis and chord total length this is a computed value and just like we have methods and variables similar we have something here called computed these are calculated variables based on things around on the whole page so we want to create one called a cart total length and every time the car changes this will also automatically update first you create a new variable let total length set it to zero now we want to loop through all of the items in the chord and for each iteration we just say total length plus equals this dot chord items dot quantity return total length and save if we now go back here you'll see that we don't have anything in the cart so then we need to make sure that when we click this this is updated automatically so if you see here now in the to list we have add we already have this button but we need to make it possible to call the the store with ux so if i just go here say add click add to cart and i can copy this go down to methods and below the get product i create it like this first i checked that the the the value inside this.quantity which is the field a pair actually is a number and if it isn't the number i just set it to one if anyone has managed to changed it somehow and then i create a new object const item product which is set to the product we are on and the quantity is a reference to the quantity up here and then to call the store we just said this dot store dot commit add to cart and plus n item so if you now go back to here we call this function and pause in item and this code will execute so if you now just refresh add to cart that did not work okay console.log add card just test that this actually is clicked on yes so why isn't this working pass in this product the quantity okay so i think i forgot to do one thing and that is inside mounted hook on the upper view i just said this dot cord equals distort store dot card because the card total length calculates this so now you see five there and if you click one more it also increases so now it's working there perfect so then i can go back to the product.view just to remove this comment and next i want to make it possible to show the little uh pop-up saying that you have added the product to the cart and to do this i just need to stop view here and install a new package called npm install bulma toast and now we can say mpn run serve again and go back to vs code and first at the top here below axios as i import curl bracket toast from bulma toast and inside here below at the bottom we have added the product to record we call toast set the message we want to show the type which is class which will show a green it's dismissable pause on hover duration which is 2000 milliseconds and bottom right of the screen and save so if i now click here again so refresh click the product was added to the cart great now i have added to cart functionality and i can set this task to done i just want to move these tasks a little bit because i want them below here below there so now i want to implement a loading bar so when we click product and things go slow between the server i want to show a loading bar so you know what's going on so if i go into store you know remember that we added this but you need to make it possible to change this so i create a new action here or mutation so set is loading so we just pause in false or true from the one of the pages and then if i can go to product for example and at the top of this function i can say this dot store commit so now we set set is loading to true and when this excels is finished we can say false like that but to make sure that we don't call false before it's finished we need to set this to a sink and a wait so when this is finished this code will execute and save so nothing will happen now because we haven't added the loading bar to the screen yet so if i just go to app.view scroll up above this section create a new div is loading bar has text center and bind this clause attribute and set is loading if state is loading is set to true so if this is set to true the loading wire will show and here i just add a div class lds dual ring and we need to add some styling to this so if i just go down at the bottom and find the style object i've already prepared this so we set lds dual ring display inline block width and height is set to 80 and then after this we had content empty set display block set width and height of the circle to 64. more genus 8 border radius and the color i will add this to the github so you can easily get it from there if you don't want to write all of this yourself then we set the keyframes because we wanted to go down up and circle or rotate we set this automatically to hidden and height to zero but when we overloading the height is set to 80. so we save this so if you save this now go here refresh you see this here a little bit while we wait for information from the server so now we have a loading bar set this to done and if i want to use this other places like the front page i can do that just copy that line find where we are loading this a sync and set it to await true and false i could set it in here but if we got an error then we need to set it to false in there as well so it's just easier to show it or remove it after so for now front refresh you see this very fast great so then we can continue to make a possible to set the document title because as you can see here it says check gets view and we want to make it possible to click a product i want to say black no brown leather instead of just jackets view which doesn't make any sense so if i for example can go to project.view and after i've got the product from the server i can set document.title this.product.name and pipe it into jackets like that and the front page you can set this in the mounted here you can just say home like that save so if you now refresh you will see brown leather pipe jackets if i go to the front page it says home great so this will be implemented all pages we create from now on so i can set this as well to done so now i want to make it possible to click winter and summer appear because now nothing happens when i go to these pages so the first thing i need to do is to go back to views.pi and create a new view set for the category so just category detail just like here and i can copy most of this just paste it remove products like okay and instead of saying product area of course a category because we want to get the category not the product i can remove the filter as a slug is category slug and the same with this one can be copied and get remove the product slug remove the product slug and here we want to use something called a category serializer which you are going to create very soon copy and paste and save so now we have the view sets but we need to create the serializer for this as well so below the product serializer we create a class called category serializer and pause in this one more time then we say class matter model equals category and then the fields we want to use is id name slug and we also want to get all of the products connected to this category and to make sure that we get all the data connected to the product as well i can pass in products equals product serializer and then money equals true and i will use this product serializer to get the data and pass it in here as well and i can copy to get absolute url i don't need the slug actually because i get it in here save then we need to import it here so we just pot products slug category slug views dot category detail dot s view and that's it for the back end so if you now go down to view again we need to create a page for showing the category so here's the new file category.view so begin template div class page category close it script name is category oops category and i know we're going to use xco so import excels from excels and i want to show the toast if you get any errors we're going to show the information that we got an error from the server and in here is data return create a new object called category and a list called products inside there and up in the template you also want a div to show the title and the product inside there so it's just like the latest product this is size 2 hashtag center and just category.name i'm about to get the category from the back end we create there go into the mounted hook mounted and call this.getcategory and now we need to create this function methods get category and we can set this to a sync as well because we want to use the loading bar here also but first we can get the categories like from the route parameters just like we did in the detail page for the project then we can set the is loading to true and to false defaults after excel's request axios dot get and here i just pass in the route to the category use this one inside there dot then response create a fat arrow function this dot category equals response dot data and here we got the category and also the products and when we get this from the server you can set the document title to this.category.name pipe jackets and if there are errors you just say catch error console.log printed in there but since we have the toast available we can show something went wrong please try again and then you show a red information so now everything there is okay but we still need to show the products but we can first import it to the router below here import category from dot slash views category.view i can make a copy of this it will be a little bit simpler because we don't need product slug we can just have it like this remove the trailing slashes category category okay so i have an error in the python code name category is not defined and that's inside the views.pi sorry i forgot to import the category model of course for now refresh something went wrong i getting 500 error from the server let's check it out what that can be category serializer forgot to import that as well sorry save refresh now we get summer but we don't have any product to show there yet but if i go to the front page to home.view i can just make a simple copy of this code go to category.view paste but instead of saying latest product is category dot products and save and then they show there but the problem now is that we are uh we are duplicating a lot of the code so this should actually be turned into a component and that is the next task in the list i think yes convert product to a component so inside the folder components we can create a new file product box dot view so this can be reused all over the page so i can just paste the same code this is the code from the front page if class column is tree we just remove the v4 and then script name product books and we need a way to post information from the parent down to the component and then we use something called props and i have one props here called product which is an object so if you try to send in anything else you'll get an error and then the last thing is to go to home and i can just remove this code go back to the product box because i just want it in here so it's just connected to this component so if we save now we should be able to reuse this code so in home dot view we can go to the top here and say import product box from at slash components that is just a shortcut for the root folder of the view project and product box like that and to be able to use it here we need to add it to the list of components and then i want to remove all of this and replace it with this much prettier code sorry one too many dips there so now we just say product box use the same v4 but here we should latest test products bind it and we bind product to the product we get here and pause it into the prop here so it can be used here as well if i go back to the front page it still looks the same but the code is reused so i can do the same for the category page if i go back to home copy this like that go to category and then i just paste it in there then i just need to import it import product books from at components slash product books and then just register here components like that and save so now it's much easier to maintain oops typo components so if i now go here there is something wrong latest product sorry did another typo here it should say category dot products save so now we have the same code on all pages but if you look closely now if i click summer winter nothing happens and this is because we need to watch the route for changes because when we switch between two similar dynamic routes the life cycle hooks won't be cold so when i click the winter or summer the mounted hook will not be be clicked or refreshed from view so we need to fix this so below mounted i create a new object called watch so this will watch changes to the route and here we can check that if to the right we're going to is a category then we call this here function again so if we now click save refresh and i click winter the products change the title and similar great so now everything there is okay so now we have the possibility to view a category to get this to done and then we want to make it possible to search we want to add a simple search bar up in the menu and then the first thing you need to do is to add some a new view so first you need to import something more from the rest framework because we need a decorator here here i want to use a simple function best views instead of the class-based views and here we use the decorator api view and we say that we just want to accept post requests to this view search which is the name of this view and then we get the query from the request data and if it's empty it's empty but if query we want to check if it is empty and then we say product equals prodigy product dot object filter and we check if the name contains the query or if the description contains the query so you just need to import this q function from django which means you make it possible to do a little bit more advanced query sets to import it we can scroll up and just at the top here we say from django.db.models import queue you can go down and continue and then we just want to use the same serializer the product serializer and pass in products return and just copy this line like that and if the query is empty we can just return an empty products list and save and then i just want to import this to the urls so at the bottom oh sorry i can be above here since this is a fixed word and not a slug so then we go to slash products search to get information from the server okay so now we have the route so then we can go back to view and continue the development there so if i just find app dot view scroll up and above the nav bar and i want this to be on the other side of the menu to do that i create a new div class app bar starts then a new dave claus with navbar item and then a formatter get action slash search slash search is here on view and not on the back end we should get back to you soon and just like the field has add-ons we have it here as well just like on the add to cart button and at first control input text class input placeholder what you're looking for and give it the name of query whoops looks weird okay like that's around the button close button is success in here we have icon which is just a search icon if it's saved now go back here you will see that we have the simple search here with this icon from front awesome so then we can create the search page which you to go to and click this to create a new view search dot view create a new template and a difficult page search and script tag name search and now i'm going to use excels here and i can import the product box like on the front page and the category page because the product box will also be used here i can create a data array return products this can be a list and then components so we register the product books here and i also want one more product no property here called query and when we open this we're going to mount it and we can set the document title to search and then a pair create some more html this is a div class columns is a multiline and then we have a div for the title and information about which search term you have searched for so search and then search term this will just print the contents of this variable close the div close that div and then below here we can call this component again and just loop through just like on the other two pages so if we save now we can import this to the router so just test it it's working import search from dot slash views search dot view and then again add it to the list here okay copy this one paste it above there search paste there and search and save so you can now go back here i can say check it hit enter search term is empty so there's something wrong or something i have forgotten to do yes in the mount that here we need to get information from the url like that so then we get the location search substring they get all of the parameters based on this url and then we can get the query from the url then we said this.query which is a reference to this to the value of the query in the url and then we can set this dot perform search like that okay just create this functionality so we have it methods perform search save so even now go back here you'll see that they have jacket in there because that's what what we were searching for now we can set this to a sync because we want to use the loading bar here as well true false after the axios so here is the evade excels and then we use dot post because we want to post the query back to the server to this route which we created and then when we get the response we can just add this.product equals response.data save and if you go back now you will see that we got this back from the server your search brown instead we should get a brown leather jacket perfect so now we have a simple search for our store which means we can go back here so this task done great so now we can make it possible to go to the cart so we can see what we have in there it possible to increment and decrement the content and similar but we can start by creating a new view chord dot view create template tag tab class page cart close it script name cart now we can just import this to the router before we continue so it's done make a copy of one of these cards card and i can copy and paste here as well chord chord chord and save so then i can click here we rewrite it here but there are no contents yet but we're going to fix that now so if i go back here i can add the title and div class column so if i save now you will see that we have the title there so everything is working as it should up until now at least and then below the title i create a new deep clause and add a d plus shadow so it's a little bit the shadow around this contents and then i add a simple table set it the full width so it fills out the whole screen and this will only show if there are products in the cart and if there are not you can see here we say we if you use that directive and down here is a vls so if you don't have any products we show this information instead and the table contains the product price quantity total and the symbol empty one for the actions here we're going to use a component we're going to create very soon where we just loop through cart dot items so if you go down here i can import xios from xcos and i can import this cart item we're going to create i just want to make something more here data return cart an object and set the empty list in there so the code up here don't crash and then i can say components so we register this with view and save so now we just want to create this before we continue so up here in the components folder cart item dot view create a template script name cart item and here we want one prop called initial light time because we don't want to change the item we get in so we need to create a new item m and pass it in back later you will understand very soon then we create a new data object which just returns the item and our set the item to the property we get from the parent and we have one method called get item total let's just take the quantity and multiply it with the product price and if you just go up here to the template again paste in a little bit of code first we have a td with router link which is connected to the product get absolute url just like in the product box here and then we just show the product name below there we have the product price the item quantity and then we use this get item total which is the method we created here for calculating the total price to fixed so it's not very many decimals here and then add a button which is not going to work yet but if we save this go back to the cart you don't have any products in the cart but that's because we haven't activated this yet so we can create the mounted who care again like this this dot card equals list store just like we did in app.view so if we save now go back still don't have any products that's wrong because we have eight up here i think it is because uh this value hasn't been set yet this is a computed value so add a new property here computed card total length and then we use something called reduce which is the built-in function in javascript so we loop through all of the functions no items there this is the accumulator and current value and then we just combine them to each other and default value is zero so it just takes zero and plus every time there is a quantity so if we save now now we see the contents here perfect so that means that this function is working as it should like it's just the this value is going up there and then for every time we go through at item it's adding the item quantity okay and below here i want to create a button for going to the checkout and also showing the totals so below here paste in the code div class column is 12 and box so i have a little bit shade around that too give this subtitle summary and then we create a new get total price which is a new computer value i'll come back to just to show the total price and then the number of items we have and then below there we have a button to cart slash checkout which will come back to you very soon so i can just scroll down this function is very similar to the total length just that it takes the price and multiplied with the quantity instead so if we save now go back here you'll see that the total is showing here and that you have eight eight times in the cart great so now we can go back here to the to-do list and set this task to done and the cart item is already a component perfect so now i want to make it possible to click plus and minus to change the quantity and the card and also click the delete button to remove it totally or completely from the course okay so to make it possible to change the quantity we go back to curve.view and then just below oh sorry we're going to cart item so it's easier to handle it there in the component so below item quantity we are decrement quantity and increment quantity plus so then we're going to create these two functions as well item and increment quantity there press an item like that now we have the plus and minus button but nothing happens when i click this but that will be fixed now so when we click increment quantity you say in item dot quantity plus one and then we call this dot update card and when we call decrement quantity is a minus equals one but i also want to check that if the quantity is zero then we just want to remove it completely from the cart so we can't go below one without it being removed from the cars then we can create this update cart so we can update back to the parent and when we call update card we just say local storage to the set item cart and then just stringify the whole object of cart which we have in the storage and since we already here we can create a remove from cart as well this will call a function back to the parent and make that remove it from the object because we can't do it directly from here since we're in the component so let's just add the button for this as well so if i go up now just replace this button [Music] where we add add click remove from cart pass in item and then it's this function that will be called so if i click this now it go down as you can see down in the left here in the summary the price changes if i refresh that process and everything has been updated perfect but if i click this now it won't uh work because we haven't done anything to this so what we need to do now is to just copy this and go to cart dot view and at the next line is a v on so we listen to remove from chords and we just say remove from cart and then we need to create this function so this is from the from the component and this is in the chord dot view so i just scroll down below no sorry methods let's create a new property and then i have a function called remove from cart in here i said that this dot card dot items equals this dot corted items and then we filter out the product we get and remove it from that list and save if i refresh now click this one it was removed from the card and the prices here was also updated perfect so then i can actually set this to done because now we have made both of these two possible okay so now it's time to make it possible to sign up and log in when you proceed to the cart or sorry the checkout okay so first we can start by creating the view for this so sign up dot view create a new template live close page sign up and script name sign up and i'm going to use axios here so import axios from xcos oops and i want to use the toast if there are an errors in the sign up form then i have a data object with the username password and i repeated password and a list of errors if there are any and inside here i had one more dip class columns and then column is four is offset fourth it's narrow and on the middle of the screen close that close that and then we can import it to the router just to see that it's working router make a copy of one of these sign f i can copy the search for example sign up sign up sign up and then i don't have any buttons for this yet but if i try to go to sign up instead i'll see the title at least below here i want to have a forum we're filling out all of the information we need so just go back to signup.view and below the title here add form and when we submit this i want to prevent the default action which is to submit it to the server we call a function called submit form we can create this so we have it down here like that then i want to add a few more fields up here first i have a div class field and a label username and a v model username which just returns or is connected to this one and then below the username i have two fields for the password which is password and password two so i can check that they're matching and similar and if there are any errors i want to use something called div class notification so we can show information there and print out error to the user and this will only generate or be rendered if the errors has length and if there is we loop through them and show them as a simple paragraph then have a simple button to submit the form and if you already have an account you can just click here to log in we can go back and see it now so we have the three fields the button or click here to log in but we don't have haven't created that yet so now i just want to create a functionality for signing up remember that everything is done in the backend so it's just here in the front end we need to change things okay so the first thing i want to do is to reset distort errors in case you try to sign up multiple times and then we can validate the username just to check that it's not empty and if it is empty we push this string to the list of errors if we save now first just click sign up you see this username is missing and then we do the same for the password but you just check password one and down here we check that if they don't match and if there are no errors now we can continue and push the information to the server and say if this.there is not this.length then we can go into this first we create the object with the username and the password which is information that will be sent to the server and then we say excels i want to use the post so we call post to this route and pass in the forum data then we get the response back from the server and we show a toast with the information that the account is created so go please go and log in and then we use distort router push to automatically redirect you to the login screen and the error list here is a little bit longer than we are used to we loop through the errors we get from the server and just push it so if you have problem with that the username already exists and similar you will show it here okay so now we can save and we can try to create an account code with stein sign up account was created and i got an error at the same time okay i got an error because the login here doesn't exist yet yes i get that category does not exist so i need to create the in login page so that is the next task anyway so i can just set this to done because i got the new account but there is an error because the login page doesn't exist so create a new file log in dot view and if i just go here now to the router we can import it log in and just copy this log in log in and save so if we now refresh we don't get any errors there so now we can continue and build the login functionality so for now just go back up to login.view paste a little bit of code it's almost identically to the sign up page you can just copy that and remove password to and change the login or sign up to login besides that it's identical i can create the script and we can import excels we can set the name to log in and we can create the data array with username password a list of errors mounted document.title log in pipe it into jackets save so now the title is set up there and i have the simple login form perfect so but before i continue and make it possible to call the backend i just need to change the store view x a little bit so in here below the initialize store i add this because i want to check if you have a item called token in the local storage and if you do we set token this object there to that value and is authenticated is true and reset them if they are not apparent in there and then we need a function to set the token very simple just said token and pass in token and then we set authenticated to true and the value of token to token and the same with remove token when we log out we just want to reset these two so you're not don't have any problems there i can save this close it for now and when we call the initialize store inside app.view i need to make a few small changes there as well first i want to get the token from the state so we know all the time if you are authenticated or not and in here we say if token so if you are authenticated we want to set the access default headers or authorization token to the token we have stored in the browser and if not we set authorization to to empty and save but then we can continue and make the rest of the login functionality so below the mounted we need the methods for creating the login function or the submit form here i want to call async submit form like that first i just want to reset the authorization in case there are anything that from the an earlier session or similar and i want to remove the token from the local storage and then i create a form that i just like and sign up but here i only have one password and then i just paste simple axios post which goes to token login and we get the response back because the new variable called token with uh in the information from response to data.org token and then we call the store to set the token with information we get from the server and we set the default header here to token so that every time that we call the server from now on we have already set the token and we store the tokul token in the local storage so we can refresh and everything will work and after that we want to go to the part where we're coming from so if we were in the course and click proceed to checkout you would be redirected to the login page and then you'll go back there after and if there are no it just be redirected to the cart when you sign in and here we just had a simple error just like in the sign up now we can save okay there's an error axios is not defined sorry i think it is in the update view i forgotten to import here import axios from excels and save so now refresh i have this i can try to log in with the user i just created log in and yes i was redirected to the cart so hopefully and probably everything was working there now so now i authenticate that as code it's time user so then i can go to the to-do list and i can set this task to done and i want the simple my account page where i can make it possible to log out so if i just go into views there creating a file my account dot view created template and script name my account and we have a simple method here for logging out this is just a function logout and we reset this we remove everything from the local storage and we commit remove token so the state is also updated and when that's done we redirect the user back to the front page of the store or the e-commerce website the template here is very simple it's just a david glass page my account and i have the title my account with the button where we when you click that you call the logout function and it's just a button with this danger so it's red and it's easier to understand what it does okay so now there's a little bit of magic we need to do in the router because we need to add something called a router guard now because if you go to my account without being authenticated we want to send you to the login page so first we can import this my account and just add it here my account my account like that so now it's just like the other but we need to append some metadata here so you can tell view that we want this to be guarded by authentication so meta object require login equals true and to make this happen we need to scroll down at the bottom here we will create the router so before we go into that route we want to check in the state if we are authenticated so below here we say router dot before each so before each route we go into we we want to loop through this code so this is a little bit complicated but we checked that if to dot match some record require login so this will trigger when this is set to true and not store.state is authenticated so if you require login and you're not authenticated we want to send you to the login screen and then we say next name log in which is the page a query just so we know we're going to redirect you to after else i can just call a function called name and then we go to the my account page so if i now go to my account you're probably here okay here is an error store is not defined i forgot to import store in the page in the index.js here so at the top here i can say import store from dot store and save so if i now refresh you will see that my account page and i can log out access is not defined forgot to import it of course import excels from excels save refresh logout and that was logged out great try to log in again call it's time like that great so now we have login functionality log out and sign up perfect so i should probably change this because we don't want to see the login button or authenticator will much rather go and show my account button that's not very hard to achieve so i just need to find app.view and then where i have the login button create paste some new code here we create a new template and check if you are authenticated and we want to show the my account button if not we show the login button so if i just save now go back here using my account instead of login perfect okay so next step now is to proceed to the checkout where you need authentication and that we have already fixed authentication so we can create a new page for the checkout so in here create a new file checkout.view okay so first we create a new template with the page checkout multiline and the title as usual oops close the div close the div and close the template and create the script name check out like that the dead object here is a little bit longer because here we have the cart stripe card and all of the information of the customer and the list of errors then we want to go into mounted as a document.title equals check out jackets and we want to set the court here to this so we get information from the state in to this one also and we need a method for getting the total of the cards or get the item totals already so for each item we get the total of the item and then i have copied the two computer values from the cart page so they are identical and then i just want to import excels before i forget it import excels from excels and then we can just changes to the template first we create a new box with a simple table inside where we show the items product price quantity and the total so here we also add the body to the table your looped record.items and set the key to product id here so the product name price quantity and i'm used to get item total that created down here and then i want a simple foot for the table where you show the total length the total price and similar so if you save this now we can go into router to import it here check out like that and now i want to copy this because i want to require login when you go to this page and i want it below here so i'll connect it to the cart and the url is cart slash checkout the name is checkout check out safe like that so now we have the possibility to go there so if we go now here proceed to check out but you don't have any products there so we can fix that first add the cart go here proceed to checkout and now we have the summary here of what we are going to pay perfect now we need to add four below here we add information like the name phone number etc so then i can go back to the checkout page and below this div i think yes create one more div with the subtitle shipping details close that div that looks okay and all fields here are required to fill out and then below this i had a div class multiline because i want the some fields there and some next to them so we don't have a very long form first i had the fields to the left the first name b model first name which is connected to this down here and then the last name the email which is type email so we have a validation from the browser and the phone and then the field on the right side will be address zip code and place so if i save now and go back you'll see that i have much more hair perfect but we need a button and a place to fill in stripe and if you get any errors from the server or from view you want to show them here so it's just like other places where we're shown errors hr just add a div element id card this is for stripe i'll come back to that soon and then we check that if the card.length is more than zero then we want to show the button where you can pay with stripe then i just need to create this function so it doesn't crash like that if i save now go back you'll see pay with stripe great actually i think this is supposed to be one more div out i'll just cut this out paste it there so now yes that looks much better so here we'll it'll be possible to add the fields for stripe soon so i just want to extend this a little bit before we go further to the next task paste in a little bit of code first i just reset this errors list then i check if the first name is filled out and etc of all of the different fields so we just save now try to submit you'll get information that all of the fields are missing but now we have a simple checkout page at least so then i can set this task to done and then i can create a simple success page before i forget it so just find the views folder here create new file called success dot view template script name success i can set the amount add to success jackets and the template will just show that your order will be processed within 48 hours whatever you want to show here to the customer save and close then we can import it to the router so it's done so router index.js success like that so go down here card slash access success like that so now we have the simple variable redirected to when the payment is done like that okay so then i just need to make sure that the that the stripe is working in the back end so that's a little bit more job so if you haven't created an account that's stripe you need to do that just go to stripe.com it's free and then you get the api keys you need and when you're done that you can go back to the settings.pi file and create a variable there i like to have it up here somewhere and it's stripe secret game and it's a very long and you need this test key and it's important that it is the secret key which you're going to use in the back end and to keep track of the orders we need a new django app so if i just go down here stop the server python managed by start app order and before i forget it i can just append it to the list of installed apps order save and close and now we need a model to keep track of the orders so find order here go to models.pi i want to connect the order to users and it import this object from django which is the user object your request you are authenticated with then i want to import the product model because the items is connected to a product then i create a new clause order which is the order model and pause in models dot model and then to connect the user to the order i just create a new foreign key set the related name to order so it's easy to get all the orders for a user then just paste in all of this field which is the contact information we are going now we are passing in in the checkout form and i want one field for uh for the date time field so i know when the order was created and then i want the decimal field so i know the paid amount so i get this from stripe and fill it out just so i know that i can double check it afterwards and i also save the stripe token that was used to perform the purchase and i changed the ordering to create that in descending order so that in the back end everything is okay and when you show the ordering and then my account page and then add a simple string representation of the object which is just the first name so it's easier to see in the back end and i want to order item as a separate model as well so clause order item models dot model first i need a reference to the order so i just do like every other foreign case and i need a reference to the product so i know which item which product it is on the item and then the price so it's easier to get i don't have to go through the product to get it and then the quantity which is defaults to one and then the stream string representation which is just the id so it's easier to see in the back end so that's the models for there and then i can update the database by running make migrations and migrate then i can run the server again great i can also close this and now we have the models okay so to make it possible to proceed to the checkout and everything is working in the back end we need to go into views slash no order slash use pi and import a few things first import strike which you're going to use to talk to stripes api and then we import settings so we can get the secret key we added to settings.pi we need to get the user i need to use http before if there are any errors and then a simple render and then you import a few functions from the rest framework like status authentication permissions and just like in the in the product slash reviews.buy then we import the two models we created and i also need to import the order serializer i want to come back to that and fix it very soon then i do create the api view and here we just want to post requests i set authentication because we want to require token authentication and that the user is authenticated then we create a new view called checkout and we want to use the order serializer with the data we get from the the form we fill out in the checkout page now we can say if serializer is valid that means that all of the data is correct and we can proceed with the checkout then we initialize stripe with the secret key we get from the settings file and then we can calculate the paid amount by saying sum and then we take the item quantity and multiply with the price and we do this for every item in the serializer validated that are items which you get from the post form and then we want to add a try here because if the payment isn't successful we need to accept this and show an error to the user first we create a new charge for stripe i set the amount to pay the amount and multiply it with 100 because the stripe wants this in cents and not in dollars i want to set the currency to us dollars because that's what i want on my e-commerce and then i just show a simple description which will show up on their bills which is a charge from jackets and source which is the stripe token we get from the front end so that everything is connected and working now just close this and when we go go through this that means that everything is working and we can save the data in the serializer set the user to request the user which is the requested user and there's a paid amount to the paid amount we calculated up here and then we return response as a 201 created so the front end knows that everything is okay and accept exception so that means that there is something wrong and if there is something wrong we need to show a 400 400 bed request and the same goes with if there is something wrong with the serializer we just show the same error and save then i can create a new urls file for the order urls.pi from django.urls import pot not fromorder.notimport views and url patterns equals credit list part okay do it like this but check out we use the checkout and the name is also check out don't think we need this but yes like that great and then we need to create a serializer for the order so inside this app create a new file serializers.point so first we import serializers from the rest framework and then we import the two models we created and we want the product serializer since it's connected to and one of the items and then i create the order item serializer class matter [Music] model equals order whoops order sorry order item this is the order item this has to be above the order serializer and the fields i want for the order item is price the product and the quantity and then below here i create the order serializer plus model equals order and the fields here i want id and all of these names stripe token and items and to get items i need to do just like we did in the product for the categories so items equals order item serializer as that manager and what we need to do now is to override the create functionality for this serializer to do that we create a new function here called def create and here we get the validated data we remove the items from there and then we create a new order based on the validated data we get from the form and then we loop through all of the items in the list and we create a new order item and set the order which is a foreign key to that item data and the product is already included here now you can save this so i think that if i now go back here and just fill out something here play with stripe nothing is working because i haven't created the function here in the com knowing the here we need to call axios which i've already imported so i can scroll down here so below here i check again if the error has length meaning that if there are not errors we can go into this and the first thing we do then is to set is loading to true and then we use this dot stripe i will show you how to edit create a token based on the chord information and when that's done if there are errors we remove is loading and then we show that there's something wrong with stripe and paste try again and then we just show the error in the console as well but if there are no errors from the backend with straight then we continue to dysfunction call stripe token handler token so then we call this function this has to be a sync function first we create a new list called items started to be empty and then we loop through all the items in the court and just do some changes here because that's much better for the backend so you get the price finished and everything and then just push the object to the list of items then we created new data from new data object with the contact information all the items and the stripe token let's try token is the one we get from the back end and when that's done below here we call await excels and then we post it to slash checkout which just created here sorry i need to before i forget it i need to go into the main urls and import it here order like that sorry about that so then i can go back to them check out yes so then we call it and when that's done we call uh the store the view x clear card so everything is clear there and then we redirect the user to the success page we created and then we just remove the set is loading so now i just need to import stripe here and make sure everything is okay so i go up and find the mounted below here i paste a little bit of code so first here i checked that if this dot card total length which is the function we have down here computed if that is greater than zero that means that we have products in the cart and we can continue so then we create a new function no new instance of stripe and a new instance of elements and then we want to hide the postal code from that stupid form and then we mount it to the element we added up here then we just as you can see here we have the stripe and chord which is just two empty objects and the last thing we need to do now i think it's the last is to import stripe in the index.html file so below the font awesome paste in the stripe url js.stripe.com v3 i think if i now refresh yes you can see that we can fill out the card number and things like that so let's try this no sorry i need to do one more thing and that is to go into the store and create the remove no clear cart function so that just clears the whole object and then remove it from the local storage now refresh and then the card number to test this you can use 42 42 42 42 32 42 32 42 and then a date in the future and one two three as cvc pay with stripe so thank you the process will in the order will be processed within 48 hours and if i go here it seems that you got post so everything there is correct and if i go to order and into admin notify i want to register this with the backend from dot models import order and order item admin dot site register order i don't need to see the order item save so then if i go here go to the front page go to orders you will see that i have an order and the paid amount the stripe token and everything seems to be working so we got success page and the stripe has got its money perfect and i want to show orders on my account page so then i need to create a new serializer so if i scroll up and find the order serializer i can copy this and say my order item serializer and this is where i want to use the product serializer like that because if not there will be a problem when you post it and you because somewhere you have the object product assuming you have id for the project and similar and then you can make a copy of the order serializer but you don't need a create function just copy it and go up here say my order serializer and i want to use my order serializer there as well and i want to get the paid amount here as a variable save so everything is okay then i need to create the view sets for this so import my order serializer and then at the bottom create a new view sets called clause orders list and then you set authentication clauses and permissions and then we override the get because here we only want to get the orders where the user is the request user which is the authenticated and we want to use my order serializers and return the data to the front end so we can save this we need to import this into the urls so below checkout we just say pot orders views orders list as view and save so now it should be possible to use this in the front end so now if i find my account and below this button create an hr and then a new div class column subtitle my orders and i created a new uh component order summary where it posts in information about the order then i need to import this component which will create soon and i need a registered component and then i want to use the mounted we can set the document title and when that's done we call a new function called get my orders and this is very similar just the the normal axios to api slash v1 slash orders and i'm going to get it to slap dish.orders to response.data just need to make sure that we have a data array as well return orders which is a list and then we can oops forgot that comma there then we need to create this file and component new file order summary.view okay so here we have the template a div class box and the order title which shows also the order id i have a subtitle with the products and the table which shows all of the different products and here we just loop through order load items which you get because we use the my order serializer which has items included down here we just say name order summary we get a prop order and we have two methods for getting the total for the item and the order total length so if i save now and expect that wait word okay because i need to go into my account again this has to be such a sync of course when i use elevate in here so now i have the order here with the products i've ordered a simpler perfect and that was really coding are going to do now so now it's time to push this code to live server and start making impossible for other people to find my store so if i just go to the to-do list i can set this task to done and the first thing i'm going to do is to deploy the django part of this project i'm going to create a server and then start accessing it i'm installing the software we need so if i go to the browser and into digitalocean and i click create up in the corner here i'm going to create a new droplet i want to ubuntu 20.04 and i just want a basic shared cpu and i can select regular intel and five dollar because it's going to be a very small server for testing i don't want any volumes it can be located in amsterdam it's close to norway a little bit at least the network name can be set to that i don't want any of this yet and password like that okay so now that was okay one droplet hostname can be just ubuntu jackets and create droplet and now this is created and i just need to wait for the server to start okay so now it's just started i copy the address try to access it ssh root at yes permission denied okay okay type the wrong password like that so now i should be in perfect and then i can go to to do list because i created the server and exit it and then i want to install the software we need so first i just want to update everything so that all of the packages and everything is correct this can sometimes take a little while and then see the apt get upgrade this will actually upgrade the packages and not just the connections to them great so now everything is updated and we can start installing some software i'm going to install python 3 pip python3 dev lib.qs postgresql postgresql contract and nginx just type that hit enter and yes i want to install that great and i also want to install cert bot and python 3 insert bot and insert but no patent reserve with nginx so we can get sl ssl certificates for the website so yes i will add all of these commands in a file on github okay so now that this does the done the next is to create a postgresql database so go back to server as i sudo dash you postgres psql so i change which user i'm logged in with then i create a new database by saying create database jackets and i create a new user jacket user with packet jacket's password and then i need to do some changes this is for the role and something to do with the configuration for django and then i want to grant all of the privileges to this user to that database and then i quit by saying backslash q so now we have postgresql installed and the database is set up with the user we can use then i want to upgrade pip just so i know that that is also for with the newest version and i want to install virtual environment so we can use that just like we do locally and then i want to create a new folder in web apps slash check cache which we should read a base for all of the projects here we can go into it then i want to create a user group for the user i'm going to call the group web app so we can use the server for multiple web apps or web applications or django websites then i want to create a user by saying sudo user ad system group id so i want to put it in the web apps set the default shell and the home folder to web slash jacket under the name of the user which is jackets hit enter and since i'm already in this folder i want to create the virtual environment by saying virtual env environment 382 and hit enter and then i can go into it saying cd environment also i don't have to go into it but i can activate it environment bin activate so now it's activated here just like it is locally and then i want to install the same packages here that we have locally and to do that i can go back to visual studio code stop the server as i pipped freeze then i will get the list of all of the packages we have installed locally so if i just copy all of this now create a new file here called touch req dot txt vi or q and paste it in there and i can install of all of them saying pip install r req.txt now note that we have the same packages on the live server as you have locally so that means that there are no differences in the environment for python and i need to install another pip which is cycle pg2 binary this is used to connect the django to the postgresql server next step now is to move the django files from locally to the server normally i would just use git but to make it easy i can just use i can just send them by using scp so here i go up one folder and say sip or check go jackets django dot zip check at django now i've got a folder with all of that and i can send it by saying sap r so root at and then i p like that sorry i forgot to specify which folder i wanted to send django jackasjango.zip like that so now it should be sent here and then just make this a little bit smaller cpu root put it there and then i just say unzip jackets jungle can it install unzipped and then i can unzip it great just removed a zip folder just to make sure that i don't have any problems with the the permissions for the folders and similar if i do this you will see that the root is owning everything here now and i want it to be owned by the jackets user so ca mod ch phone sorry dash r jackets colon web apps dot ls lord again and then you'll see that now i own all of the files and folders so don't any permissions wrong there or anything like that but i want to make a little change to the cd jackets and into jackets jungle i want to copy the settings file because i want the separate settings file for the production so this would be called settingspro.pi and settings prod change the database here just remove these lines and then i paste information about the postgresql server we created so by the name of the user know the database the username password and localhost because i'm the same server as the postgresql great so now we need to update the database but to do that i need to make a copy of the manage.pi i should buy how to create a profile for this as well and h prod because i want to use the prod file for updating the database so now i can say python management pi make migrations sorry manage prod by make migrations and migrate so now everything should be updated and created in the back end perfect next step now is to install g unicorn g unicorn will be the web server for django so pip install g unicorn i want to go up one folder and inside the environment i want to create a script for running the g unicorn server so vi environment bin g unicorn underscore start and then i paste in some code i set the name to check its django the directory for django socket file it should be created automatically which user to use which group which settings module to use and i would use the wsgi as i mentioned in the beginning of this tutorial and then just go into the django there start something and execute it i will add the these files in the github so you can get them there if you want and then you need to make this run the ball by saying chmod plus x environment then unicorn start you can try to run it supposed to be jackets here check it like that maybe that will work now no cd slash web apps check it environment jackets okay now i know why it should be like this because the jacket django is not in the environment folder okay now it's starting the problem was that if i go into the script again add the wrong part here because you need to go back one folder and then into the environment then bin then activate and the same down here so now the unicorn is starting perfect next step is to install something called supervisor supervisor will make sure that the t unicorn script is running at all times so install supervisor by saying apt install supervisor and when that's done we can create a script or just a config file that will make sure that the unicorn is running at all time so if you go to cd e2c supervisor conf create a new file touch jackets dot conf vi gen gets of course that's not correct that will fix it create new program jackets django the command we want to run is webs slash jacket environmentary a2 bin g unicorn which is the great script we just created we want to use the jackets check gets its name of the user and then a log file here i need to create this folder and then it's just some environment configurations so okay there so i have the log file and then we need to update supervisor by saying supervisor re-read first just to check that it's available supervisor ctl it's available of course and then update and now it was added to the group if i now say status it says starting now it says running so now hopefully django should be running in the background next step now is install nginx nginx is the web server out to the world so when we get the request to engine x we use that as a proxies to reach g unicorn and we need nginx to handle the media files for django so install nginx that have all so already installed nginx we did that in the beginning so we just need to create a new config file so e2c and genex sites available and then vi check api jackets dot code with with stein.com which is the address for the web server i'm running on now so first we create the upstream app so this will connect to the g unicorn socket file which is created by the g unicorn script and then we want to listen to port 80 and if you come from port 80 which is http we want to redirect you to https and then we want to listen to 443 which is what https is at the back max body size and access log error log and ssl certificate and i search the certificate key i will fix it after this is done and then set some protocols and just make sure that ssl is working here is the hosting for the static files and here is the whole thing for the media files which is the uploaded files and similar and and we use the proxy to forward you to the jackets app server which is the socket file we created so now everything there should be okay i'll also add this file in the github repository i need to activate this now see the sites enabled s create a symbol like link back to that file we created check it no api there now we have it here and we can restart nginx so service and gen x restart okay there is an error okay it can't load the certificate so that's the problem here so the problem is that they can't load the certificates so we need to obtain them search bot dash ng next hd and indeed the domain name okay maybe if i just skip using nginx cannot load okay i just need to remove this for now so now i get it enter email address called stein gmat.com agree yes okay so then we got that sorry um yes redirect and then i can obtain this where we will host the view part of this project and then redirect okay so now we have the ssl certificate and we can try to create the symbolic link again restart nginx okay there's a new error okay i restarted the server and now everything seems to be okay so if i go to api check it dot code with stein.com get a bad gateway so i need to check the log server log files web apps check it snow environment okay there logs ch own super okay so our problems is to be with the g unicorn so i need to find out what that is failing this couldn't create this one okay permission denied so then i need to go to this folder and it seems that root is owning this folder so i need to change the permissions restart and also i want to restart supervisor supervisor ctl restart jackets hit enter okay what's the status check it's django refresh great so now it's working i just need to add this to the list of allowed hosts via django settings prod so i need to find it first of all i can add http s i can add this here because this is the one i'm going to use for the front end and here i need to add it to this list as well restart jackets django refresh found perfect but it seems that it's working so i can just try to log in to create a product sorry i need to create a super user so source slash environment bin activate python mentioned by manage product by create super user of course headers jungles always something you forget to add just want to edit here and to the list here as well so i need to have two of this like that now we need to restart again then we can try to create the super user admin admin jackets.com and the password and then we can go here login with the user i just created great create categories winter winter and summer summer and i can create a product as well in the winter warm jacket warm check it the description 199 select the picture save so now we have products there and if i now try to go to api v1 products latest products then i get it there perfect okay i need to change this as well sorry that's the last thing we need to do in the back end yeah project models.pi it shouldn't be this address of course it should be this maybe even without the lost slash there restart refresh and then we have them here perfect okay so i just need to check if the files were applied uploaded media uploads okay the picture isn't there okay we'll come back to that very soon just want to make sure that we have uploaded engineer view as well so everything is working except images so then i first want to go in here and go to main.js and change this url to api jackets dot code with style.com and save so now that would be the address and then we want to compile all the view code so we can upload it to the server as well to do that we say npm run build and understand we have a new folder here called this this is all of the compiled code in like html and javascript and similar and we need to upload this to the web server just want to zip it first zip dash or dist dot zip and dist so then we can send it to the server so sap dist dot sip and then the address sorry root at like that and then my password and now that's there so then i can go up one folder and say cp root dist there unzip dist so now i have it here but i want to create a new folder okay there check it view and move this folder inside there oops that's wrong and the jackets underscore into jackets view and call it dist and if i go in here now unless lord you will see that root is owning this and i need to fix that great so now the next step is to create a new config for view now for nginx so cd e2c engine x sites available touch jackets dot code with stein.com the i jackets and paste them so we do the same thing here we listen to 80 and redirect you to https and then we do the same here with setting up jackets.com at least in 443 set the ssl it's at the correct part to these which we have also already obtained and we set the root folder to web apps slash should be jackets here sorry check it check its view dist and the same down here jackets so save and close i'm going to sites enabled and lms dot slash sites available jackets there there and restart oops i was not supposed to service and gen x restart sorry i start to get a little bit tired now so sorry for all the mistakes so if i now try to go to this address yes everything is working there we got the product from the live server but the image isn't working sorry other wrong parts for the media files so it's supposed to be like this media and i need a space at the beginning save close restart and now the image is there and hopefully if i refresh the image is there as well so now everything is working as it should so i can go to the to-do list and everything can be set to done here now now i have a working e-commerce website built at django and view so this is a really cool project you can use in your portfolio similar just remember to change the styling and just change a little bit more functionality and similar the code might not be ready for production and you need to change the stripe api keys for production as similar but i hope you have learned a lot anyways if you have any questions feel free to leave me a comment below and answer as soon as i can
Info
Channel: freeCodeCamp.org
Views: 183,507
Rating: 4.9615531 out of 5
Keywords:
Id: Yg5zkd9nm6w
Channel Id: undefined
Length: 165min 26sec (9926 seconds)
Published: Tue Apr 06 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.