How to Build an E-commerce Website with Django and Python

Welcome to this tutorial where we’re goingto be building an e commerce website using Django. To get started, we can just clonethis Django project boilerplate repository that we have on GitHub. So you can just copythis link. And we’re going to clone it here. And so with that, we can then change intothat repository. And I’m going to open it up in Visual Studio code. And so we can thencreate ourselves a virtual environment are then activated. And we’re just going to gohere into the requirements. And I’m going to change this to Django 2.2 that we’re goingto install.We can then type pip install, dash our requirements dot txt. And with thatinstalled, we can then get started. Hey, everyone, before we jump into this, if you’re interestedin becoming a better Django developer, then check out just Enroll and you’llget access to exclusive video courses every month on Python, JavaScript, and react witha specific focus on obviously Django. The link is in the description below. So now thateverything is installed, we can make use of this management command that we have in ourcore app. And that’s the Rename command, which allows us to rename the project. So all weneed to do is just called Python rename, and I’m gonna call mine DJ ecommerce.And now you can see it’s been renamed to DJ ecommerce.And there it is. And let’s tryand run the server. And there we go. We can see we have two unapplied migrations. Andthat’s because of moving over to Django 2.2. So we can run Python, manage that py migrate.And there we go. Now we can run the server again, and cool. And we can go and open thisup in the browser as well. And okay, we get this no such file, which is static in E andV, that’s a directory that we just need to create for our static files.So just createdthere. And if we try again, now we’re just getting the generic four, four, which is fine,because we don’t actually have any URLs. And so before we start coding, I’m just goingto say that this tutorial is not for absolute beginners, if you haven’t worked with Jango,before then rather watch some of the other tutorials on this channel, before you jumpinto this. And it is assumed that you have an understanding of HTML, CSS, JavaScript,and Django as well. So if you are not that comfortable with all of those concepts, thenthis is going to be difficult. And we’re also assuming that you’ve seen some of the othertutorials on this channel where we’ve covered things like authentication. And so if youare not familiar with any of that, then again, rather watch some of the other tutorials beforeyou look at this, because the pace will be quite fast then. And otherwise, if you’recomfortable with all of that, then we can actually get started here.So let’s go andsearch for Django, all auth, because that’s what we’re going to use for authentication.So we’ll just go to the read the docs, and we just need to install the package. So let’scome here, we’ll stop the server, and just type pip install Django, all auth then weneed to bring the authentication back end. So inside DJ e commerce settings, we’ll goall the way to the bottom and add authentication, then we need to go and add all of these installedapps, so sites and all the all auth apps. And we can do that here inside installed apps.Hope paste them there.And then we can scroll down, specify the site ID as one. And thenwe need this URL pattern added into our URLs. So we’ll come and add it there. And I’m justgonna change it to a path and remove that regular expression. There we go. And thenit just says we need to migrate. So we’ll say Python, manage that py migrate.And cool.There are all of those migrations now. And we can go and run the server. Now and if wetake a look here, at account login, and we have a login page, we should be able to login with an admin user. Cool. So I am, you can just create your own admin user to login.And so we were successfully logged in. So that’s the basic installation of Django allauth we will look at styling this later on. And so the next thing going to be creatingour models. So we’re going to do this inside core models. And this is going to be everythingthat defines the logic of storing an order, and the process of adding an item to an order.And we’ve touched on this in the shopping cart video that we did, which I’ll link inthis video as well. So if you haven’t seen that we did introduce some of that logic here,but we’ll go through it again.So the basic concept is that we have an order item. Andthis comes from model stock model. And I’ll say pause for now. And then we have an order.And this is so that we can link all of the order items to that order. And the order,you could basically view as the shopping cart. So we store all of the items that the userhas added to the cart inside this order. And every time they log in, we fetch the orderthat they have, and display that order with kind of like a shopping cart item count inthe top right corner, like you see in most ecommerce websites, and will also define somekind of Boolean field on the order to say whether it has been ordered or not.So ifit’s not ordered, then this will be the order that is being used until it is ordered. Andas soon as it is ordered, then the next order will be created after that. Now even thoughwe have an order item, we will still need another class, which will be the item. Andso the order item is just a way of linking between the order and the item itself. Sothe item will be displayed in a list of items that you can purchase. But as soon as youadd it to the cart, then it becomes an order item. And this is kind of like an intermediatestep, a link between these two models. And you can then handle very specific logic aboutthe order item here inside this class. So let’s just pass in some basic fields. Fornow we’ll add a character field to the item, we’ll just say maximum length is 100. Andthen we’ll define the string method and just say return self dot title. And I’m just goingto copy that and paste it for both of these as well, then we’re going to need to makeuse of our author user model.So that comes from Django settings. So we’ll say from Django,dot con, input settings. And then we’re going to associate the order with a user. So userequals models dot foreign key with settings dot auth user model, and we’ll say undeleteequals two models dot cascade, will add. And ordered field which we can say is models,dot Boolean field default, equals false. And here I’ll say return user dot user name asthe string representation. Then we’ll also specify the items as a many to many field.And this is of the order item, so that we can add these order items into the order.And then we can also add something like a start date.So the moment that the order wascreated, and we can say this is a date time field, and we’ll pass in auto now add equalto true. And then we could say, an ordered date equals models that date time field. AndI’m not going to pass anything in. So we’ll manually set that value the moment that itis ordered. And then here in the order item, we can link that to this item model. So we’llsay the item equals models dot foreign key with the item. And I’ll also just specifyundelete as cascade, then here in the item model, this is where we’re going to definethe price. So this can just be a float field, just like this. And then if we pull up ina terminal, we can try and run the server. Cool. So that’s still working, we can thentry and make these migrations. So let’s run, make migrations. And then we will say migrate.And we can also then go and add these into the admin. So just say from dot models, importitem, or the item and order, and then call admin dot site dot register.And we’ll justadd these in. And now we can go into the views and just create some basic views here. Sowe’ll say define, let’s say the item list. Just take send a request and say return renderof that request, which we can just go to item list dot html. And we’ll create some contextwhich we’ll need to get those models. So say from dot models, import item just for now.And then we can say, this context has items, which can just be item, dot objects, dot all.And then we’ll bring that into the core URLs.So I’ll say urls.pi. They’re also from Djangodot URLs, import path, and then say our URL patterns equals to a list. And we’ll justuse an empty string. And then just say, from dot views, import item list, and then we cango into the DJ ecommerce URLs. And we already importing include. So we’ll create anotherpath that just goes to an empty string and say, include core URLs. And also specify anamespace as core. And then if we say run the server, it says we need an app name.Sohere in core URLs to say app name, equals core, there we go. Then we can just go intothe templates and our create item, list dot html, we’ll say that it extends from basedot html. And then we’ll create a block content. And inside here, we can just say, Here isthe list of items. And say, for item in items, men and four. And I’ll just, I’ll just sayitem, like this. And so now if we go to that base URL, with these get that rendering out,but we can also then go into the admin. And we’ll just create some items. There we go.And there we can see them coming through. Okay, cool. So everything is working so far.And now what I’m going to do is go and grab a template, which is the MD bootstrap ecommercetemplate.So you can go to MD bootstrap, comm slash freebies slash jQuery, slash ecommerce.And I’ll also link this in the description. And here, you can download this for free,which we’re going to use in our project. It has an MIT license, so we’re going to makeuse of this. And so that’s just because one, we don’t want to spend time designing, becausethat’s not the point of Django.And two, it’ll look a lot nicer. And everyone likes to workwith something that looks nicer. So you can go and download this for free. I already haveit. So I’m going to bring it into this project now. Okay, so there we can see the project.And basically, we want to take all of these static files, bring them into our static inIan v folder, and then everything else we can bring into the templates. And I’m prettymuch going to delete everything else that’s not an HTML page.So let’s just grab all ofthose folders, bring them into static. So there they are. And then the checkout homepageproduct page, I’m just going to bring into the templates. And then we can get rid ofthat. And so if we take a look at the homepage, this is basically what our base dot html needsto make use of. So what I’m going to do is just go to the view here, and change thisto home page dot html. And then if we go back here, and refresh this, we’re not going toget any styling. Sure. So let’s go back. And what we’re going to do is just add in thestatic reference here. So just start by saying loads static.And then in these h refs, andin all of these scripts here as well, and then all the images are going to add thatstatic command. So for example, static like this. Okay, let’s try this again. And thisis what it looks like. Cool. And what’s nice about this, as well as that we get a littlebit of guidance as to what we need to make work. And if you’ve watched the tutorial serieson how to build any blog, with Django, then this is the same kind of concept. Once you’vebeen given a template, you just figure out what needs to be rendered and what kind ofdata needs to come through. So immediately, just looking at some of these These items,you’ve got a category sport where you’ve got a title, gray blouse, you’ve got to kind oftag here. So best seller, and you’ve got the price.And that blue as well. If we inspectthat, you can see it says primary color, that’s why it’s blue. So we could define also a labelcolor. And that way, then you can specify that in the model. So that when you createthe item, then you could output whether it’s the primary color, or it’s the secondary color,etc. So that’s some of the fields that we could then define on this model, the itemmodel. And we also see some pagination here. And if we scroll up, you’ve got some kindof filters that you could filter by category, a search bar, and you’ve got a cart item count.So what I’m going to do to end off this video, so the end of this video, what I’m going todo is in these files, the checkout page, and the product page, I’m going to make them extendfrom a base dot html.And the base that HTML is basically going to be kind of what we haveright now, it’s just going to be the blocks. And it’s just going to make use of all thescripts and the links that we have here in this head. And so I’ll show what this lookslike, when that’s done. Okay, so now I finished the templates.And this is what it looks like.As per usual, we can go to the checkout page. And this is what it looks like when you checkout. And this is what it looks like on kind of like a product detail page, I would assume.So now that we at least have something that we can work with. In the next one, we canstart with the logic of adding to the cart and removing items from the cart, and thatwhole checkout process. So let’s just start by running the server, I have the virtualenvironment already activated. And so this is what it looks like. So let’s just go down.And we talked a little bit about these product items in the last one, how we could take someof the information we’re seeing on this card item and bring it as fields on the model.So that’s what we’ll start off doing. We’re going to create a category. So you can seelike sportswear outwear shirt, and then we’ll create the label as well.So that’s goingto give us this blue or red kind of label. For more information about this specific item,we already have the price and the title, we can just go into core models, and take a look.So there’s title and price. So let’s add these ones in. We’ve got the category and then thelabel. So what I’m going to do is just create some category choices.And this is going tobe a tupple. And the first entry is what goes in the database. And then the second entryis what’s displayed. So let’s just take a look here, there’s Mike shirt, sportwear,and outwear. So we’ll just put them here. So shirt, sportwear, and outway. And we’lljust put s, SW, and o w. And we’ll just take this here. And we’ll say that the categoryequals to a character field. And also that the choices are the category choices. Andwe’ll say the maximum length equals two because that’s how many characters maximum lengthis here. And then I’m going to copy that and actually just copy the entire thing thereas well. And we’re going to make this the label choices. And then this will be the label.And it will come from the label choices.And if we just come back here and inspect this,then you can see this is danger color. And we could change that to primary color. Mostlikely we could change this to secondary color. So you can see all the different classes thatwe can add. So that’s just going to add three for now. We’ll add primary, secondary, andactually we’ll make this lowercase. And then we’ll add danger. So this could be p, s andD, and also the maximum length is one. Cool. So those are the fields then covered in termsof these items as we can see so far.So if we come back, we can make migrations. So let’sjust run Python managed up py make migrations up, we’re not putting any commas anywhere.So let’s make sure this is a tupple. Try that again. Okay, not saying we need to provideone set of defaults, and that’s correct. So for the category, we can just say providedefault And I’ll just say s for shirt. And then for the label, we’ll add a default andsay, p for primary, there we go. And we can say migrate. And let’s go and run the server.And we can then go to the templates, go into products dot html. And if we open this up,and just come back here, we only need to grab one of these cart items. And then we can justloop through all of them, and just open up home dot html. And there’s still quite a lotinside here. But if we just scroll down, after the second and third slide, we could probablyremove those as well. And you’ve got controls. And you’ve got categories.So that’s fourfilters. And then as we scroll down, then we’ve got card content, and card image. Sothis is one card, it’s inside the grid column. So if we come down, you can see that that’swhat’s repeating itself. So we can actually close it on the dove on this column. And you’vegot an entire row like that as well. So what I’m going to do is actually just remove oneof these rows.And then if we go inside this one, I’m going to delete those three columnsthere. And I’m going to remove some of these comments as well. So inside this row, I’mgoing to loop through it. And we can go and take a look at the view that we have for homethat HTML. So we can come here and add this context in there as well.And then we canloop through the items. So we’ll say, for item in items, and then just say in for theninside this card, all replaced that number with item dot price, then that is the title.So item dot title, then you’ve got new there. So this new as the label. So danger will replacewith the label display. And the way that we get the display is by calling get then thefield name. So get underscore label underscore display.So this will be item dot get labeldisplay. And I’m just going to leave it as new for now we’ll figure out how we can changethat text later. And then this is the category. So it’s very similar to get labeled display.This will be get category, display. And if we take a look at this now, then there wecan see our two items coming through. And what I’m going to do is actually just go backhere into the view. And I’m going to change this into a class based view. If you haven’tseen our video on class based views, then be sure to check it out, the link is goingto display over here in the top right corner. And in that video, we cover everything aboutclass based views. So I’m going to make use of them here, because they can help in makingus write a lot less code. So what I’m going to do is just come here to the top, and we’llsay from Django dot views dot generic import list view.And I’ll import the detail viewas well. So the home view right now is kind of like a list view, because we are listingout these items. So what I’m going to do is just come in here and we’ll say, class, homeview, which inherits from the ListView. And then we just have to specify the model, whichis the item, then I’ll say that the template name equals to home dot html. And if we thentake that home view, we can bring that in here. And I’ll replace it like this is notas view. And everything is still working. Now if we come back here, now they’re notdisplaying anymore. And that’s because the context variable is different. So if we comeback up top here, and we’re we’re looping through the items, it’s not items anymore,this would be object list.There we go. Now they’re coming through. And then we can alsogo into finer detail view. And I’m going to get rid of this function based view there.So I’ll say class product, detail view. Or rather, we can call it item detail view. Andthat’s going to inherit from the detail view, say the model equals to item and the templatename is going to be equal to product, not HTML. And that’s basically this view here.And if we just take a look at what that looks like, you can see it’s kind of like detailview, even though these images have nothing to do with this item here. I can imagine thatthis is supposed to be kind of like a detail view where you can add it to cart. So we’lltreat it like a detail view.And I’m going to come into the templates and rename productsto product dot html. And then we can save this here. And then inside the URLs, we canbring that view. So item detail view, instead of product. And then we’ll make a product.And I’m going to make it taken a slug, just like that. And I’ll change the name to productthere. And the reason this has to take in a slug is because this is a detail view.Soeither we pass in a primary key, or we pass in a slug for the class based view to handlewhich object it’s getting. And so then here inside product or HTML, we can just scrolldown a little bit. And this is the image there. Then here, we have some categories. And I’mgonna get rid of two of them there, because we only have one. So this will then be objectdot get category display, where object is the default template variable name. And ifwe take a look here, that seems to be like a previous price. So the $100 is a discountprice, which you could add in to the model as well. But for now, what I’m going to dois just replace the 100 with object price, then here in home dot html, let’s make surethat we can actually redirect to the absolute URL of each instance.And I’m just going todo that here inside this href. So we can make sure that here on this model, we have a getabsolute URL. So I’ll just say define, get absolute URL, which just takes itself. AndI’ll just say that it returns a reverse, which is going to need to be imported. So up hereat the top, we can say, from Django dot shortcuts, import reverse. And we’re going to reverseto the core namespace. And let’s just move these files around. And then to the productURL, like that. And we need to pass in keyword arguments, where the slope will be self dotslug. And that means we need to go and add a slug field here. So we’ll say slug equalsmodels dot slug field. And then we can say Python make migrations, I’ll providea default, and I’ll just say, test product like that, then we can go and migrate. AndI’ll run the server. And then here, we need to just go into the admin to fix those slugs.So if we go to items, this can be test product one.And then this can be tested product.Two. Cool, so now we have that reverse working. So we can take the get absolute URL and bringthat into the home dot html. and here we can say item dot get absolute URL. And if we comeback here, then if I click on the title, then it redirects us to that URL. And we can seethat the shirt tag is coming through even though this isn’t the shirt, and we’ve gotthe $100 price there. And we also have a couple other fields here, you’ve got a description,and you’ve got kind of like a previous price, or rather, this is the actual price. And thisis the discount price. So what we can do is we can come here on the item. And we can say,that’s the price. And then we can say this is the discount price. But we can say, blankand no equal true so that you don’t actually have to have a discount price.And then wecan go and make migrations migrate, run the server. And if we go into the admin again,then let’s go to these items. And I’ll add a discount price of 50 to that one, and I’llkeep the second one blank. So let’s go back, then here we want to display, then what wewant to do is we want to say if there is so how we’ll do this is we’ll say if there isa discount price, then show the discount price, otherwise show the normal price. And thenif you click on that item, then here will show this original price if there is the originalprice, but only if there is a discount price. So let’s just come back here and in home dothtml. We’ll create a little bit Have logic here.So we’ll say, if item dot discount price.So if it has a discount price, then show the discount price else will show the price, andthen just say endif. And we can kind of copy that logic there. And let’s just come backto home. And now you can see that 50 is showing me, which is the discount price. And let’sclick on this item to go here. So then in product HTML, I’m just gonna paste everythinghere. So again, this will be if object that discount price. So if there is a discountprice, then we’re going to show all of that. And the 200 is what’s being scratched out.So that is the price. And then we’ll show discount price next to it. Otherwise, we’lljust show object up price. And let’s make sure that this is inside a span as well. Sojust like that, and then we can delete all of those there.Now, if we come back, nowwe can see that one there. But let’s just go back to home and see the second one. Andnow you can see only the 200 is shown. And let’s actually also come back and add a descriptionon the item. So this is just going to be a text field. Again, make migrations. defaultis going to be this is a test description. And just add some nonsense there. And thenwe’ll say migrate. Cool. So now we have that field. And we also have the list view andthe detail view working. And let’s actually just go back here and add this href.And I’mgoing to add it over this div there. And let’s just come back here to home. Now, if you clickon that item, then it redirects you as well. Cool. So now let’s look at how we can addan item to the cart. So I’m just going to close that there. And we’re going to needto create a function that can handle that. So one function that will add an item to thecart, which is basically just going to take that item creates an order item, assign theorder item to the order, if the user has an order, and if otherwise, then it will createthat order on the spot.And then when you remove the item, then it’s just going to removethe order item from the items field. So we’ll just come here and define add to cart, whichis going to take a request and a slug. And the slug is the slug of the item so we canadd that specific item. So let’s say that the item equals and we’ll say import get objector four, four, so we can use this method and just pass in the item and say with a slugequals to slug, then we need to see if the user has an order or not.So let’s just checkif we’ve imported it. So we’ll need order item and we’ll need order. And then here,we’ll just say that the order item equals to an order item, which will create. And we’lljust say that the item equals to this item that we just got now. And then we need tocheck if the user has an order. So if they have an order, then we will basically justmodify the quantity of this item in the order. And we don’t have a Quantity field on theitem at the moment. So we can go and do that now. We’ll say quantity equals models dotinteger field. And we’ll say default equals one, so that when it’s created, by default,it’s only one item.So let’s make migrations, and then migrate in run server. So here, we’regoing to say that the order equals to order dot objects dot filter, and then we’ll filteredbased on the user. So we’ll say where user equals request dot user, and where is orderedequals false. So or rather ordered. So this is where we’re making sure that we’re onlygetting the order that has not been completed because they might have some orders that arecompleted. So we need to make sure that we pass this into this filter and if this orderquery sets exists. So we’ll say if order query set dot exists, then we will grab the orderfrom this query set. So we’ll say order equals to order query set of zero. So then we needto check if the order item is in the order. So we’ll say if order dot items dot filter,where the item double underscore slug equals to item dot slug, and we say if this exists,then that means that this item is already in the cart.And we can then just say thatorder item, dot quantity, plus equals one, and then say Order Item, dot save. And I’mactually realizing now that this quantity shouldn’t be on the item, it should be onthe order item. Because here’s where we want to keep track of how many order items we have.So let’s just save that. And then let’s make migrations. And let’s just see, okay, we haveto save this file. And basically just moving that field, now we can run the server again.So this is all if the order query said exists. But if the order query does not exist, solet’s say else, then we will say order equals to order that objects, not create where theuser equals request dot user. And then we just say order dot items, dot add, and justadd that order item. And then after all of that, then we can just say return redirect.And I’m going to redirect us back to the slug of the item that we just added.So this isgoing to be we take a look at the URLs, this is going to be product. So core product, andthen keyword arguments. Where slug is the slug that was passed in. And then we’ll justimport the redirect from Django dot shortcuts. And everything seems fine. So now this addto cart view, we need to bring into the URLs as well. So we’ll just bring it here. Andwe’ll add another path. And just say this is add to cart, which is also going to takein a slug.And then say add to cart and say name equals Add To Cart as well. And thenwe can take this name of the URL, come back to the model. And we’re going to create anothershortcut method here on the item. So we’ll say define, get, add to cart URL of self.And we’re going to basically return the exact same thing here. But this is going to go toAdd To Cart view, and we just pass in the slug as well, then we can use this in thetemplate.So if we go to the products dot html, and also get rid of that descriptionthere, because now we have our own ones, we can say, object dot description. And herewe have the Add to Cart button. I’m going to copy this button, paste it outside theform. And I’m just going to comment out the form for the time being, and I’ll change thisto an a tag. And I’ll say the H ref goes to object, dot. And I’ll just copy this to getAdd To Cart URL. And then I’m going to get rid of the type Submit. So now if we refreshthis here, now if I click Add to cart, and says order data can be null. That’s right.So this is the order date here on the order. So that means that here when we create theorder, we just need to pass in the order date. So I’m going to just specify that here. Andwe’re going to import from Django dot utils.So Django dot utils, import timezone. Andthen we can take this and say it equals to timezone dot now, so it returns in a way ornaive day time, depending on the settings. And this is okay for what we want to do. Sothen we’ll just pass this into this create method, so order date equals to audit date.And now let’s just go back I’ll refresh this click Add to Cart. And it says Add To Cartslug is not defined. And this is because we’re using a redirect not a reverse call here.So let’s just change this from keyword arguments to slug, equals slug. And let’s come backand try that again. Cool. And let’s also open up the admin. So we can see, if we check theorder items.And it says, We’re getting this error there, that’s from our defined stringmethod. Let’s say return, we’ll actually use an F string here. And we’ll say return selfdot item dot quantity. And I’ll say of self dot item, dot title, because the item hasa title. And this is meant to be self, not quantity. And we’ve got a bunch of them frompressing that button. So let’s just go and delete all of these. And it’s come back andsay, add to cart. And then it redirects us back to this page, which is fine.And nowwe can see one of dummy item one with a quantity of one. And let’s go back to the order here.The items not selected at the moment. And that’s because we probably didn’t do thathere. And we didn’t, so we checked if the order item was in the order. So if it was,then we just added one. But if it wasn’t. So else, then we need to say order dot itemsdot add. And we’re also adding the order item in there. Cool. So let’s go back and deletethat order item again. And then we’ll say add to cart, refresh this, there it is goingback to the order. And now we can see it’s added. And let’s see what happens if I clickit again. And if we refresh here, then we can see that there were two now. So let’sgo back to the order items and see what’s happened is that we’ve actually created asecond one, and set the quantity to two, whereas we would have actually wanted the originalone to have a quantity of two.So that means we have something wrong here in this method.And that’s that we’re creating the item every single time regardless of whether it’s inthe order or not. So one way we can control this is by changing this into the get or createmethod. And then here on the order item, we could also specify the user as a foreign key.And then also specify ordered in the exact same way that we do have it here. And thenwe’ll just make migrations. And it’s saying that we’re going to need to add some defaultuser. So what I’m going to do is, I’m just going to set blank and no equal true on theuser. And I’m just going to quit, make migrations again. And then we’ll migrate. And then let’srun the server. Then here in the admin, I’m going to just come here and specify the userfor both of these.Then I’ll come back and remove blank and No. And then make migrationsagain. And now it says there are three options so we can ignore for now. And then we’ll migrateand then run the server again. And then back here in the view, we are getting or creatingthe item. But there’s a couple other conditions we’re going to add in here. So we’ll say wherethe item equals that item, the user equals request on user and ordered equals false.So that makes sure this last one ordered equals false, that we’re not getting an item that’salready been purchased.So if we come back here, we can actually delete both of these.And then I’ll come and add to cart. And that’s because we need to add creates a day becausethis is returning a tupple to us. Try that again. Now we see that one there. And let’sopen up the orders. And we see it’s added in there as well. If I add it again, let’srefresh this here. Now you see the quantity is two and we don’t have another one createdthere which is good and it’s added in there as well.Cool. So that’s all working. So wecan now focus on removing from the cart. So if we come back here, it’s also similarlygoing to look like this. So we’ll say define, remove from cart, which takes a request anda slug. And at the end of all of it, we’re going to return a redirect back to that slug.And we’re also going to need to get that item. And we’re going to need to get the order.So I’m going to copy that query set there. So we check if there is an order for thisuser. That is not ordered yet. If the query city exists, then we get that order. And I’llsay, else, we could then just return a redirect back to that same place there. And I’ll say,add a message. So saying, the user doesn’t have an order. And then if the order doesexist, then we will check if the order contains that item slug. Or we can get rid of thosetwo there.So we’re getting the item, checking if the user has an order. If they do havean order, then we make sure we grab it. And we then filter the order for that specificitem slug. If that order does contain the order item, then we need to remove it. Sowe can basically change this to remove. But we also need to get that order item.And wecan just say, get rid of that else there. So the order item will just grab here, usingthis call there. And just say dot filter, where item equals item use equals requeston user ordered equals false. And we can just say, of zero. And then here, we’ll just sayelse, return another redirect. And here we’ll need to add a message saying that the orderdoes not contain this order item.So like that. So let’s see if this logic is correct.We’ll take that, bring it into the URLs. And I’ll just copy that and say this is removefrom CT. And then we can go into the template. And I’m just going to go into the product.And we’re going to copy this here just for testing, we’re not going to actually keepthis here. So I’ll just say remove from cart. And we can go to the model as well. And thenpaste this here and say get remove from cart URL. And then this is also removed from cart,then we can take that here. And I’ll get rid of entire line. And then the class er saysdanger. And so let’s see this now. So right now, we have to have this item. So if I sayremoved from cart, let’s see here, this still exists, which is fine. But if we come here,now it’s not there anymore. So it was successfully removed. If I try remove from cart again,then we’re not seeing any of the errors come through.And that’s fine. So we’ll probablywant to add messages as a last touch for this video. So I’ll just close these two off. Andwe’ll go to the top and also from Django dot contrib import messages. And then we can comedown. And I’ll add here we’ll say messages, dot info of the request and say this itemwas added to your cart. And then we’ll copy that and put another one here and say thisitem was updated. And I can say item quantity was updated. And then I’ll copy this and pastethat one there. So there we go, we can actually make use this one. So this item was addedto your cart, and then further removed from cart. If the order curious that exists. Thenhere when we remove the item, we’ll say this item was removed from your cart.And thenOtherwise, we’ll say this item was not in your cart. And then you can get rid of thatcomment there. And then here, we say the user doesn’t have an order. So we’ll say, you donot have an active order, and then get rid of that comment there. And because we havethese return statements, inside these l statements, I’m actually just going to add the returnthere. And get rid of it there. Because we are checking all of the boxes in these conditions.Now we just need to add the messages into the templates here. So let’s just close outthere. And I’m going to come back here and just look for the Django messages.Come hereto the framework. And if we just scroll down, and we can copy this here. And we’re goingto the templates into base that HTML. And right here below the nav bar, just paste thatthere. And actually, if you go to MD bootstrap, calm to the jQuery Doc’s components, alerts,you can actually just make use of these alerts, which we’ll use for the messages. So I’m justgoing to copy that over there. And instead of creating an unordered list, I’ll get ridof the unordered list. And paste this over here. And then the message I’ll cut out andpaste there. And then the messages tags, I will take and replace primary with that there.And I’ll just get rid of that. Now, let me actually try and move this into the body instead.And what I’m actually going to do is take the return redirect and make sure that thisis also inside all of these conditions. And just rearrange that. And then this last oneover there.So if I click Add to cart, now, we can just inspect this, and double checkthat we aren’t getting an alert, which we are, there it is. And what I’ll do here isjust coming out margin, top 20 pixels. And it’s it’s got to be quite a lot for us tosee it. So what I’m going to do is just create a div here. And I’ll specify the class asmargin top five. So then if we try this again, and we can see it there, if I try and takethat PT for class. And you can see it’s probably as good as whole get, but let’s just comedown. And you can see there are dismissible ones. So let’s take that. And now just pastethat inside there. And then take the messages tags, replace warning with that day. And thestrong, I’m going to remove and put a message in there. And we can get rid of that one.So now if we come back here, if I say remove from cart, and oh, we need to add PT for there.So if I click Add to cart, there is that if I click Remove from cart, if I try removefrom cart again, it says the item was not in your cart.And if I go and refresh thisorder here and delete this order, and then come back and remove from cart, you do nothave an active order. If I try add to cart, then it was added to the cart again. And youcan see there it is. So this is what we have. So far, we have a list of products. And wecan view a detailed view of that product and we can add it to the cart or remove it fromthe cart. And in this video, we’re going to focus a lot on just improving the displayof the site. That being authentication as one part, if we go to accounts login, youcan see here is our login page. And we’re going to try and style this to look a littlebit better. We also have some links that aren’t working such as this products link. And we’regoing to try and touch up this page as well. And also add a count of how many items arein our cart.Let’s go and jump into the HTML to start fixing some of the style. And thefirst page is the home that HTML that will fix up. I basically want to just remove thiswhole banner here. It’s not really necessary on this, you’d like to use it for something.So this is, there’s the third slide. And it’s everything inside these carousel items thatwe’re going to remove. There’s the second one. And there’s the first one. So there itis this entire slide stuff, basically just going to remove that.And these indicatorsas well. And then we will get rid of this whole div here that has the controls as well.So now let’s take a look. And there we go. Then I’m also going to remove the downloadlink there at the bottom. And I believe this isn’t actually in this file, this is in thefooter. So here we have the social icons. And right above, there is the call to action,we’re going to remove that, refresh this. And there we go. Then I’m also going to removethe product link there. So that we can do inside the navbar. And we’ll just get ridof it there. There we go. And then the home link, and checkout link. And we’re actuallyalso going to remove, and we’ll just say that this DJ ecommerce, this logo is what you’llpress to go to the home view here, I’m just going to comment this out, because maybe youwant to use it to specify something there.And okay, that style is a little bit messedup. So let’s just comment out the list items instead. There we go. And so then here onthe right hand side, we don’t want to show the cost if the user is not authenticatedyet. So we’ll come inside here. And I’m going to copy that list item. And he will say, ifrequested user is authenticated. Then we will show that item. And I’ll say else, then we’llshow this item. And we’ll get rid of that eye tag there. Get rid of the span there.And this is just going to be login. And then the H ref here. I’ll specify it as a URL.So this will be Account Login. And if we refresh that, now it says login. If we click that,it takes us to this page. And what I’ll also do is add another list item here and say thisis logged out. And we’ll do another one for sign up. And this will be account, sign up.And this is account lockout.So if we refresh this, never you have it. And so to style thispage, we’re going to need the templates. And that comes from Django all auth scarab repository,so we’re just going to search for it. And I’m just going to download it. And what you’regoing to want to do is just go in the auth directory, and copy the templates directory.So Copy that.And then when you come back in here, you’re going to want to paste itand make sure you don’t overwrite our templates folder already. So I’m going to add it inhere. Okay, there it is. I’ve added the templates directory, and I’m going to move those threefolders there. And then we have the base that HTML file that it uses. So I’m going to copyall of those contents. And we’ll paste them here in ours. Then I’ll remove this div thathas all the links, because we don’t need that. And I’ve removed block content because wealready using block content. And I’ll take the extra body and put that underneath there.And also get rid of the messages because we already have messages here.And then I’lltake all of that stuff that’s inside the head. And I’ll come pasted there so we can get ridof ours. And then other than that, there’s nothing else so we can get rid of all of that.And now we have access to these templates. So I’m going to delete that templates directory.And we can go into the account login dot html file. And if we compare this to the home dothtml file, we basically want to see what containers we need to put our content inside to makeit look consistent.So there would look to be the main and the container for clothes,the navbar there, there’s a section and then a div with row while fade in. So I’m actuallyjust going to copy that and then we’ll just try and paste all of that here inside theblock content. And of course, we don’t want the navbar so I’m going to get rid of theentire navbar. And then we’ll just close off all of these tags and I’m going to take allof this And just cut that out and paste that here in that row. And we can try and tab thisin. Cool. So that’s what it looks like. So if we go back, and let’s just refresh thispage.And okay, let’s come back in here. And we’ll add a div with a class of column 12.And then down here, Okay, there we go. And I’m going to remove the text center. And Ithink we’d probably like to make use of Django crispy forms. But until we install that, let’sjust change the class for this, submit or sign in button to button primary. And thenthis all says button, default for the Forgot Password. So if we refresh that, and so let’sgo and install Django crispy forms, we can just say pip install Django, crispy forms.There we go.I’m also going to say PIP freeze into requirements dot txt. And now we needto go into our settings. So DJ e commerce settings, base, and we’re going to just goto the bottom here, also for crispy forms. And this is just going to be the crispy templatepack, which is bootstrap four. And then in login dot html, I’ll go here to the top.AndI’ll just say load crispy forms tags. And here at the form, I’ll change this to crispy.And then we can refresh this. And okay, not a registered library. That’s right, we needto add it in our installed apps as well. So here, just add crispy forms. And we can comeback and refresh this. And that looks a lot better. And so perhaps, we’d also like tojust bring that in a little bit.So if we just come up here, this could be column six,and offset three. And there we go. I’m not going to go and do the signup page as well.But as a practice, you could probably try and do that yourself. You can see it’s prettystraightforward. So if I go and login, then it redirects us to accounts slash profile.And what I’m going to do is just go here to the base.pi. And down here, I’ll say thatthe login, redirect URL equals slash, so that we can at least redirect to a URL that wehave on the site.And there it says you’ve signed in. And we also have the option tolog out, I’m going to go and log out and just sign out there. And let’s try and log in againto see if the redirect works. And it does cool. So now we can work on this pagination.And this is actually very simple. If we just go back here, I can close this. And all weneed to do is just go to our view. So that’s in core views. And it’s the home view. Soinheriting from a ListView. And we can specify the paginate by which is a field on the class.And we could say paginate by, let’s say one just to see that it works. And if we comeback and refresh this, now we see that there’s only one. And we can just change these numbershere to match the query set. So let’s go back into home dot html.And we’ll scroll downhere to the pagination. And so right here above the nav, I’m going to add a conditionand say if is paginated. And this is something being passed in by the class based view, soin the context, and then right here underneath it, then also and if so if we come back, nowyou can see that it is paginated, which means that this is a variable in the context. Andthen here above the previous error, I’m going to say if the page object dot has previous,then we will show this link and then just say and if. So if we go back, refresh this.Now that arrow is gone, because this is the first page of the query set. So you can’t,you can’t go backwards you can only go forwards. So right here we’ll do the same kind of logic.Just say if page object dot has next and then say endif. And we do So now we need to addthe link inside this H ref.And this is going to be question mark page equals two. So we’resetting the page variable. If I set this equal to two, and we just see what this does, thenif I click it, it takes us to page two, and there’s the second item. So instead of itbeing a static variable, you want this to be dynamic. And this is going to come fromthe page object. So we’ll say page object dot next page number. Then if we refresh this,and let’s just go back to page one, and you click it, then it goes to page two. And thenwe’ll do the same thing for the back arrow. So if we come down, so in there, this willbe page equals page object dot previous page. Number nine, we can refresh this. And we canclick it, that’s because this is disabled.So let’s refresh this. And if you click that,now you can go back between those pages. And just to be simple, I’m not going to outputall of these numbers, I’m only going to show the current page that we’re on. So what I’lldo is get rid of all of those items. And we’re only showing the active item. And this isgoing to be equal to page equals page object DOT number. And then we’ll I’ll put that exactsame thing over there. So now let’s refresh this. And it says to nonce is one.Cool. Sothat’s at least working. I’m gonna go back here to the view, though. So let’s just closetemplates. And back here, I’m going to paginate this by, let’s say 10. And then we can refreshthis. And now we don’t have page two. So there we go. And so now let’s display the currentitem count here in the navbar. And we’re going to do this with a template tag. So here insidecore, we’ll just create a template tags directory. And inside, they will create the cart templatetags, which will be a Python file. And here, we just need to say from Django import template.And then we need to import our model. So we’ll say from core dot models, import order. Andthen we’ll say that register equals to template dot library, this so that we can registerour template tag. And we just have to define a function, which is going to be the nameof the template tag. And we can say this is the cart item count, which we’re going tosay takes in a user.And above this function, we just say add to register dot filter. Andfirst we need to check if the user is authenticated. Because if they aren’t, then we don’t wantto show that they have something in a cart. So we’re going to say that the query set equalsto order dot objects dot filter. And we can check the model here on the order. So we canfilter it by the user and say we’re user equals to user. But also, making sure that orderedis false. So we don’t want to get their previously ordered orders. And then we’ll just say, ifthe query is said exists, we’ll return query set of zero. So getting the only order inthat query set, and then we’re going to get a count of the number of items in the order.So we’ll say dot items, dot count. Otherwise, if the user is not authenticated, then we’lljust return zero. So now that we have the cart item count as a template tag, we justneed to go into the navbar, because that’s where the cart count is displayed.So righthere at the top, we’re going to need to load in our template tag. So we’ll just call load.And this is going to be the name of the file. So that’ll be caught template tags. And thenwe can take our function name. And we can come down here to that number one. And herewe just pass the request on user, which is already in the template.And then using thepipe operator, we can call our cart item count on there to display the count. So let’s seewhat this looks like. If I refresh this says it’s not registered, and this could be justfrom not refreshing the server there Go. Now we see there’s one item in the cart. And wecan try and remove from the cart and see which one it was. And there we go, now it’s backdown to zero. If I add it to cart again, now it’s at one. And that sums up what we wantedto do in this video. If you’ve enjoyed it, leave a comment down below and let us knowwhat you think so far. In the next few videos, we’re going to get started with the ordersummary displaying all the items in the cart, and also taking a look at that fancied checkoutform that we saw earlier on. So in this one, we’re going to focus on our cart right nowif we click on this button, it doesn’t take us anywhere.And that’s what we’re going todeal with. Now, we’re going to create a view that can display all of the items that arein the cart, and also add functionality to either remove the item from the cart, or increasethe quantity of that item. So first, we’re going to need a view. So let’s come here insidecore views, and racha. Beneath the home view, I’m going to create the order summary view.And this is going to be a detail view that inherits from now we just need to specifythe model as the order. And then we’ll say that the template name equals to let’s say,order summary dot html, then we can take this, bring it into URLs. And we’ll just createa path there which can go to order summary. And I’ll use the exact same path as the name.And then we’ll make sure we use this order view. Cool, then we can go intothe templates.And we’ll create that file. So that’s order summary dot html, let’s justmake sure that we don’t put this inside the accounts folder. There we go. Now I’m justgoing to copy everything from let’s go with home dot html. just paste it all there. Andwe’re going to need to make use of a table here. So if you go to the MD bootstrap.comdocs in jQuery tables, here, they are some examples of how to use tables using theirstyling. And I’m just going to use the responsive table, we just come down all the way there,then we can grab hold of this code, I’m just going to copy it.And we don’t need any ofthese links or buttons. So everything there in the nav bar we can get rid of. And thesection for products almost to get rid of that. The pagination, I’ll get rid of as well.So we’re just pasting it inside this container. And let’s just save that. And we’ll go toslash order summary. And okay, mistake, either primary key or slugging. That’s right. Soactually, we’re going to do is make this inherit from view instead of detail view. And we canjust define this on our own. So what are some of you then we don’t need any of that.Butwe need to define the get method. Let’s take since self ogs, and keyword arcs, I’m justgoing to say return a render of the request. And this is going to go there. And you canpass in self dot request. There we go. And Alright, so there’s our table showing, wecan come back here and just above the table, we can actually just tab it in Karachi, I’lljust add an h2 and say, order summary.So here in the table, we’re just going to displayinformation about the items that are added into this order. And that means we’re goingto need to take a look here at the order item. So we have the actual item. And that meanswe can display pretty much all of this information. So the title, the price discount price. Ifwe want to we could display the rest of these, although it might not be that necessary, addan order summary. Then we still have the order item so we can specify the quantity of thatitem. So that’s basically what we’re going to display. So here in the table, we’re goingTo create those columns, and the first one is going to be the item title. So that’s thetitle here on this model, then we can display the price. And then we can display the quantity.And then we can do the total item price. So meaning if you have a price of $10, and thequantity is two, then here, we want to see the total item price, that would be 20. Sowe’ll do it like that. And that means we only need four columns there.And we actually,we don’t need all of these rows, we can get rid of that. And here, we’re going to loopthrough the order. So we’ll say for item in object, dot items, and then just say n for.And this should rather be items dot all because it’s a many to many field. And actually, wecould add another column in here and just put that hash back as like the increment.And then here, we’ll put the count inside the for loop.But for now, let’s just getthose fields displaying. So that’s going to be item dot title. And we just need to makesure we’re going to be getting order items. So that means we should rather call this orderitem. And then this will be Order Item dot item dot title, then we have the price. Sothat’s going to be Order Item dot item, dot price. And then we’ll have the quantity. Sothis is just going to be Order Item dot quantity. Because that’s on the order item model. Andthen we have the total item price, which let’s just put some question marks there. So ifwe come back here, we aren’t passing anything into the context yet. So that means here inthe view, we’re going to need to get the order. So we’ll say that order order dot objects,dot get, and we’ll say user equals self dot request dot user, all say ordered equals false.And then here at the top, we can import from Django as exceptions.So we’ll say from Djangodot call dot exceptions, import object does not exist. And then we can just say, try dothis. And then say, except object does not exist, then we’ll have to raise an error.So we could either raise it, or we could just say return a redirect, and just say, to slashfor now. And we can just say, messages dot error. And we’ll say, parsing this requestand say, you do not have an active order. And just pass in self dot request. And wemight as well place that there. So now if we come back and refresh this, now we haveanonymous user object is not iterable. So we need to ensure that our user is authenticatedfor some of these views. One of them clearly is the order summary view. And some of theseother views would be like the add to cart and the removed from cart.So let’s go importfrom Django dot contrib dot auth dot decorators, and we’ll import login required. So here onthese function based views, we can at least say app login required above both of these.So we ensure that you have to be logged in to call these methods. Then for the ordersummary, we’re going to need to do the same kind of logic. And we’re going to use a mixinfor this. And this is just almost from the same path. It’s from Django dot contrib dotauth dot mixins. And we’re importing the login required mixin. And then we just come hereand pass it in as the first argument that our class inherits from. So that now if wecome back and refresh, this now redirects us to the sign in page and let’s just signin. So now we’ve signed in, and we aren’t getting anything showing there. And that’sbecause we still need to pass this audit into the context. So let’s do that. Now. We’llsay this is the object and that is the order and then just pass the sin.So there we havethat item. There’s the price, there’s the quantity. And now we need to think about howwe can display a total item price. And we could simply do this on the order item. Sohere on the model, we could define a method that takes the self quantity and multipliesit by the item price. So we’ll say, define get total item price takes itself. And wecan just say return self dot quantity, multiplied by self dot item, dot price. Now, we alsohave the discount price. So that means that we’re going to need a method that does thesame sort of logic, but for the discount price. So we’ll just say get total discount itemprice. And instead of multiplying by the price, we’re going to multiply by the discount price.So then here on the order summary, we now need to know if the order is on sale, or ondiscount, then we’re going to display that discount total price.Otherwise, we displaythe normal total price. So we’ll just say if Order Item, dot item, discount price. Soif there is a discount price, then we’ll say else and say and if so again, if there isa discount price, then we’re going to output the get total discount price. So like this.And then Otherwise, we’ll just get the normal total price.And we could put dollars in frontof that. So refresh this now. And we get 300. And that’s because this item is on discount.And what we could do to make this even fancier is by creating a method that gets the amountthat the person is saving on this item. So we can say, Get amount saved for self, andjust say return this method. So self dot get total price minus the discount price. Andthat’s how much you’re saving. So then we can come back here. And if there is a discountprice, then we’ll say saving. And then say Order Item dot get amount saved. Come backhere. And there we see saving $300.And we could make this a little bit nicer with alabel. And we can come back here to see those components. So if we go components, tags,labels, and badges, and then just scroll down here for this span tag. And then we can putthis all inside a span tag actually. And then just come here to the end. And let’s see whatthis looks like saving 300. And we can get rid of the brackets there. I’m just goingto leave it like this small just to show you the principle and how you can create extrafunctionality like this pretty quickly.And let’s just go and add another item. So thisone is not on sale, I’ll add that to cart. We’ll go back to the codons, let’s actuallyget that URL there. So then the nav bar here to the cart, we need to add an href here.And this is just going to go to a URL. And let’s just check what that URL name is. Andthat’s all the summary. And if we come back, refresh this. And we forgot the namespace,let’s just check what the namespace is so cool. There we go. Now, if I click caughtnow takes a stay. Cool. So both of these items are displaying the correct total item price.And now we want to display the order total.So that would just be summing both of thesevalues together. And we can also go and fix this order number there. So let’s just goback here. And we can change this to be for loop counter. And then just refresh this.There we go. Now that’s looking good. And so in a similar way That we did here by checkingif there is a discount price and then displaying it otherwise displaying this, we’re goingto create a similar method that does that same logic here on the order item, which isbasically to get the final price.And that’s just so we don’t have to keep repeating this,if there’s a discount price logic. So we’ll say define, get final price. And we’re justgoing to say if self dot item, dot discount price, return self dot get total discount,and then say otherwise return self dot get total item price. And this is so that on theorder, we can calculate a total. So we can just say, Get total. And here, we’re goingto do this in a lazy way by saying the total equals zero. And saying for order item inself dot items, dot all, then we’ll say total plus equals to order item, dot, get finalprice.And then just say return total. And then here on the order summary, right offto the table, in its own row, I’ll create one column. And this is going to be object,because that’s the order. And we’re going to say dot get total, and then just put dollarsin front of that. And okay, this is inside the for loop, let’s make sure that that’soutside the for loop.And there we go, we can just make sure that this is spanning acrossthe entire table. So I’ll say column span equals to five. And then we’ll just come here,above it, and I’m going to create another column. And this one, I’m actually going togive the column span of four. And this is just going to say, order total. And I’ll saythis is in bold. And we can refresh that. And also make the total itself bold. And thenwe can also go and add another row. And this row is going to be just a column span of five.And we’ll say that there’s a button in here, or rather an anchor tag. And I’ll just sayProceed to Checkout.And for now, we can just say that this href takes us to slash checkout.And then check this Yeah, then we can give this a class and say button button, let’ssay warning. And I’m also going to say, float. Right. Cool. And I’m just going to changethis to four as well. Okay, there it is, if I click on that, it takes us to this checkoutpage, and also add another button in there. So let’s just display them here. So this firstone we can just say is primary. And it’s going to go back to just slash for now. And we’llsay, continue shopping. And I’m going to change the order of those two. And I’ll just say,margin left. So continue shopping takes you back here. And then lastly, here inside thefor loop, we’re going to need to handle if the cart is empty.So if it’s empty, thenwe’ll just display a row. And then this is also just going to be one column. And we cansay column span equals five. And we’ll just say your cart is empty. And our copy thisrow there, we can get rid of this Proceed to Checkout. So all you can do is just continueshopping. And then we also want to make sure if there is an order, then we display thisorder total. Otherwise we don’t display anything. So we’ll say if object dot get total And thensay end if, and then we can check this out. So let’s say we go and remove those items.And we can actually add some buttons here, right next to the quantity. So we can changethat. So here, let’s go to this order item quantity, we’re going to add some icons inthere. So if we come here, I can just search for icons, and you get an icons list.AndI’m just going to search for plus. So there we go. So I’ll take that, and we can put thaton the right hand side. And then if we search for minus, copy that one, and paste that onthe other side, then if we see what this looks like, and I’m just going to say margin, rightto and margin left to, there we go. So we want these tools to be buttons. So we’re goingto wrap them in anchor tags. And we’ll just output this a little bit better.Call it savethis, refresh that. So now there are buttons, at least. And this is going to be the Removefrom cart. And the plus is going to be the add to cart. Because if we take a look hereat the views, we have functionality to check if that order item is already in there, thenwe’re just incrementing the quantity. And then here in the Remove from cart, we actuallydon’t have that functionality. So what I’m going to do is just copy that, paste it here,and this is going to remove, maybe let’s call this single item from cart. So we’re gettingthe item checking if the order exists. If it does, we grab the order, we check if theorder item is in the order. And instead of removing it, we’re just going to decreasethe quantity. So if we see how that was done on this add to cart, we’re grabbing the orderitem quantity and saying plus equals one.So here, we just say minus equals one, andthen save it, don’t remove it from the cart, and then just say this item quantity was updated.And then I’m not going to redirect back to the core product. Instead, this is going tobe order summary. And I’m just going to leave it like this on that one. So now let’s takethis and bring it into the URLs.And then we’ll just copy and paste that there. Andsay this is remove single item from cart. And we’ll say remove item from cart like that.So now we can use this in the href. So if we minus the href is going to be a URL, whichwill go to that URL, and then we need to pass in the slug. So that’s going to be Order Itemdot item dot slug. So let’s go and test this out. And this is call as the namespace.Andokay, let’s go back to the copy. So now if I click minus and it’s returning a redirect,oh, we’ve forgotten, we don’t need to pass in slug into that URL. So now let’s just goback, refresh this. Okay. Now we’re on four. If I click that, now we’re on three. Cool.So that is working. If I say plus, we haven’t linked that one yet. But it’s going to bepretty similar.So let’s just paste that there and make sure that we use the Add to Cartname. And let’s refresh this. If I click Add. And okay, we’re redirecting. And it actuallymight be a good idea that it just redirects back to the order summary in that view, aswell. So here in Add To Cart when we increment the quantity, we’re just going to go redirectthem there. And also in that case, and in that case. Cool. So let’s refresh this goback to the cart. Click the plus. Right, we don’t need the slug passed in there anymore.Okay, refresh that. And let’s test it again. Now. So we see it seems to be working andThe pricing is also changing along with that course.So that’s pretty good. Lastly, I thinkwe could add a trashcan here on the right hand side, which could be if maybe you have20 of the same item here, and you don’t want to click the minus button to get back to zero.So you’d rather just click the trashcan. So that means here in the order summary, in thislast column here, right here is where we’re going to add another one of those icons. Solet’s just search for trash. And I’ll copy that one. Paste that there. And just makesure we wrap this in an anchor tag as well. And instead of it being removed single item,this is going to be the removed from cart.So that is just removed from cart. So pastethat there. Cool. Let’s refresh this. And let’s also go and add here float, right. Justrefresh that. There we go. And I think we could also add some style and just say coloris red. Refresh that. Cool. Now, if I click to delete that, okay, let’s also go back hereto the view removed from cards, we’re going to say goes to order summary, and get ridof the slug. And otherwise, these two will just let it redirect back to the product.That’s fine. So let’s go back here to the cart. And if I click to remove it, your cartis empty, continue shopping, add to cart, redirects us back here, increased quantity,decrease, if I subtract again, then we’re on zero.Now think how we should handle thisis if it goes down to zero, then it’s removed from the order. So let’s go here to the view.And this is the Remove single item. So here, we’ll say if Order Item, dot quantity is greaterthan one, then we will subtract one from the quantity. Otherwise, we should just say, removedfrom the order. So order items, remove that order item.And I’ll bring the order itemssave there as well. So that seems right. Let’s go back here. And let’s increase the quantity.Okay, now if I subtract, now it’s gone. Cool. So all of this seems to be working prettywell. And in the next video, we can get started with that checkout view, and look at how wecan handle the billing address and shipping address of the user. Alright, so this is whatwe have so far, we have these items, we can view them, we can add them to a cart, we cango to the cart and see them here. And we can proceed to checkout, where we’re now dealingwith this checkout form. And so this is what we’re going to be handling in this video.And basically just handle the process of getting the user’s billing address and physical addressto ship to and at the end of this, then being able to redirect them to the payment methodthat they select. Now, there’s also some stuff on here that we’re not going to use, suchas the first name, last name, username, and the email, because we already have that, butwe will keep most of this.And so let’s go into that checkout form HTML file. So that’stemplates, and then check out that HTML. And here is everything. And I’m going to get startedby removing everything we don’t need. So that’s this last name and first name, I can get ridof the entire row there. We don’t need the user name. We don’t need the email. So ifwe save this, and refresh this, and there’s quite a big gap here. So let’s just removethis class there and see what this does. Yeah, that’s much better. And one thing to noteis that we’re not going to display this name on the card credit card information here,because there are options to select your payment method. And we’re going to handle that ina separate view, not in this same view. So we can go down there and get rid of all ofthat. So that’s this entire row here with the name on the card and credit card and theexpiration date as well. So this entire row and if we save this Cool, and who also comehere to the credit and debit card, I’m going to get rid of one of them here.And let’sjust say this is stripe for now. So now we need to think about the type of form thatwe’re going to create, are we going to use a Django form or are we just going to useplain HTML and accept the data in the post request? Now, I’m more proud of the methodof creating the Django form. So we’re going to do that we’re going to go into coal andcreate and say, from Django import forms. And we’ll say this is the checkoutform.And so it comes from forms dot form. And if we look here, at the form, we havethe address, which is kind of like the street, and then we have the other apartment, or sweet,the country, the state and the zip code, now there’s a package that we can use to handleselecting countries, and that we’ll get into in a bit, but the state, we’re not going touse, so I’m going to remove that option and only use the zip code. If there are packagesthat handle the states, then you can obviously go and add another field to take that inputin. But we’re just going to remove it for simplicity. So we can get rid of that columnthere. So back here in the form, we’re going to start adding those fields. The first onewas the street.And we’ll just say street address, we’ll say this as a character field,then we had the, let’s just call it the apartment address. And so this is also a character field,and I’m going to say required, equals false. And that’s just because here it says it’soptional. So we’ll go along with that. Then we have the country, and we can make use ofDjango countries, which is a package we’re going to install. So here, you can go to theGitHub repository. And you can see all about it. So if we click on installation, all youhave to do is just run pip install Django countries. And I’m going to run PIP freezeinto the requirements. And there we go. Then I’ll run the server. So we need to go andadd Django countries to our installed apps as well. So here in settings base, I’ll comeup here and just add this in. And then we have an example, country field. So all wedo is just import the country field from Jango countries, and then specify that field onthe model. So that’s what we’re going to do.We’ll come here into forms. And there’s acountry field. And I’m going to specified in the exact same way. And here, they actuallyhave blank label as a parameter, which can just be select country by default. So we cando that. Cool. So that’s the country, we’ll see that in action in a bit. Then we havethese zip code. So I’m going to say zip equals forms dot character field as well. And thenwe have this option, shipping address is the same as my billing address. And we’ll thinkabout how to handle this. But for the time being, let’s just keep going. Then we havethe save this information for next time. So these are both checkboxes, and I’m going toadd them in but we’re not going to deal with functionality for them just yet. So we havesame billing address. And we’ll say this is equal to forms dot Boolean field.And I’mgoing to say that the widget equals to a checkbox input, then we have save info, which is alsogoing to be a checkbox input. And then we have the payment options. So there will havepayment option, which will be also a Boolean field, I’m going to say widget equals formsdot radio select. So that way, we can only select one at a time. And so let’s start takingthis into a view. So we’ll come here. And this is going to be inside the checkout viewhere. And I’m going to change this into a class based view as well. So we’ll call thisthe checkout view. And I’m going to make this inherit from the default view. Then we cansay define the get request. And then we’re just going to render that self dot request.And then we’re going to need to get our form and pass that into the context.Then we havethe POST method, which also just takes in ogs keyword dogs. And they will deal withthe post request of that form. So let’s go and say import from dot forms, the checkoutform. And then here, we’ll say form equals checkout form. And I’ll say context. form,is that form. And then I’ll just pass the context in here. Then the same kind of logichere, form equals that and we’ll say request dot post, or none. And this should be selfdot request, then we’ll say if valid, I’m just going to say print form as valid,then we can just say return a redirect to, let’s see what URLs we have.Yeah. So we cango back to checkout. So that’ll just be core Checkout, like that. And now let’s take thatcheckout view, and replace it there. And then view. Alright, so now let’s come backand refresh this. And now we’re going to need to go into here. And I’m going to come justto the top here, and create another form, passing the CSRF token. And then I’ll putthe form. And we also have Django as crispy forms installed. So we can come to the tophere, and say load crispy forms, tags. And then here on the form, we’ll say crispy. AndI’m just going to add a button as well. And I’ll just say class is button button primary.And say type is submit. Now let’s refresh this. And there’s a spelling mistake thisCSRF.Okay, and then let’s just come here and say, check out. Alright, so there’s ourform. And we’ll worry about the styling in a second, we’ll get it to look like this.But we have the street address, apartment address, the zip code, same billing address,save info, and then we aren’t getting the payment options coming through. And that’svery simple to fix, we can just come here and specify our payment choices. And thisis going to be a tupple of topples. I’ll say the first one is just s, which is for stripe.And then the second one will say is p which is PayPal.And then we just specify thesechoices here in the radio select. And this is not meant to be a knee. This is meant tobe as a second argument. And it’s changed this to a choice field. Alright, let’s trythat again. There we go. Now they’re coming through. And you can only select one at atime, which is correct. And now we can worry about styling this to look the same.So whatwe need to do is take a look at the HTML. So let’s go back here. And inside this form,we need to look at all of the fields. So you can see that, for example, this first one,the ID of address, has a class of form control, but it’s inside these divs. So what we coulddo is instead of outputting the form, just like this, we could loop through all the fieldsin the form or just access the fields directly. So for example, I’m just going to commentthat out. And here I’ll say, form dot dot street address, because that’s this field.So if I come back and refresh this, now it’s still there, it loses the placeholder. Butwe can come and specify the attributes inside here. So I’ll say widget equals forms dottext input. And I’ll say attributes where the placeholder is let’s get that exact sameplaceholder here.And then we can come back and refresh those. And there we go. There’sour placeholder. So we can go and do the exact same thing for the rest of these. So I’lljust comment this one out. And you’ll say form dot, and this is the apartment address.And then here we’ll grab this exact same widget posted in there. And the placeholder willsay is, apartment or suite. Let’s take a look. Okay, there we go, apartment or suite. Thenwe have the country. And we can go and see how they output the country. And actually,let’s go back here to the form and we’ll say, dot form field. And let’s come back and refreshthis. There we go. Now we have that country field showing up and you have all these countries,which is pretty cool.So we can come here, back inside the HTML. And here, when we choose,we basically can just comment out the entire select field, and then just output form dotNSS. country. And we can see here it has a class and an ID, so we can go back. And inhere, I’m just going to specify attributes. And let’s see here, if class. And we’ll getthat class here. That’s custom select. So like this. And then if we come back here,and cool. So that styling works in the zip code is simply just the zip code. So we canjust come here and say form dot zip, and refresh this. And cool, same thing. And then we cancome back. And now we have this shipping address.So I’ll just comment that one out. And we’llsay form dot. And this is same billing as shipping, then we have the Save info. So thiswill be form dot save info. And then we have the two inputs. So I’m just going to commentthat out. And we’ll put form dot payment option. And this could not work because it’s insideone dove. Let’s refresh this. And yeah, so instead, we can just come above here and sayfor value, comment text in form dot payment option, dot choices. And then after that infor. So we’re basically creating a div for every input. And then we can actually commentout our own output there and bring back the input that was here, already.And then thetext will say is this name, you can actually change it to name. And then the value willcome here, inside the label, and I’ll put it there. Then the ID I’m going to changeto name and specify the for value as name as well. So let’s go back and see here. Andoh, we’ve got an end comment to get rid of that. And if we come down, and Okay, it’snot up putting. And this is because it should be formed on fields, not payment options.And if we just inspect this, then we can open up the label we have as as the label, butfor the input, the ID is stripe and the name is stripe. So that means that value is thisfirst value in the tupple. And then name is the second value. So we actually don’t needto use value that much. So I’m going to change it to name just so we can display it.So ifwe refresh this, now we have stripe and PayPal, the enriching comment out that second div.So let’s come back. Cool, and we just need to make sure that they’re both not checked.And now you can notice that we can actually select them both. And that’s because the name,if we see here, the name was payment method. And if you want to only be able to selectone of the radio options, you need them both to have the same name.So payment method isthe right way to go. So we can refresh this. And now, we only able to select one at a time,which is correct. But our shipping address isn’t working. And that’s because the fullvalue is being applied to something that doesn’t have that ID. And actually, to make this alot easier, what we can do is, we can bring back our inputs, we can just refresh the page,we can inspect these two, and then we get name equals save info for the one. So we cancome here and specify that there. And then the other one is name equals same billingaddress. So we just put that there. And then what we can do is, we can say, if form thatsame billing address, then we’ll say, checked, and then say, and if and then we can takethat, bring it here in the input, form that save info then checked.And you can get ridof that and actually remove some of the spacing there. Okay, or refresh this, come down. Andthere we go. And then we can also go here to the form. And we can say required equalsfalse for both of these because they’re not required, then we can come back and refreshthis. And we can see they’re both checked by default, let’s just add on the end of thesedot value. refresh this, there we go. Now, by default, they’re unselected. And now everythingseems to be working. So we can go and remove the form that we created up top. So that formthere. And okay, so the styling is all gone there.Okay, so we can just go here to Djangocountries. And we can make use of the country’s select widget. So we can just import this.And then here, when we call dot form field, we can pass in the widget as this country,select widget. So now say widget, like that. And then inside there, we can specify thoseattributes. So this will be class. And that class is that there. And then if we go backand refresh this, there we go, now we’re getting that styling coming through. And then we canjust dial that zip code, which just has form control. So we can go back here, or say widgetequals forms dot text input, and specify the attributes. And then just say, class, form,control.Come back. And there we go. Alright, so now all the styling looks fine. Now wecan handle what happens when we actually submit the form. So back here in the view, we havethe post request, and we’re just going to print that form, cleaned data and see whatcomes through. So we’ll just refresh this, enter some stuff in here, select a country.I’ll select both of those, and let’s say stripe continue. And okay, we need to make sure thatform is a POST request form. And we must add a CSRF token. So let’s try again and selectstripe. And we didn’t return a response. So here in the view, obviously, our form is notcoming through correctly. So what I’m going to do is say print, self dot request, dotpost. And then here we’ll say return. We’ll do the exact same return there and we’ll justsay messages. dot info, or we could say warning, and pass in self dot request and say failedto Check out, then we can come back.And if we enter some data, okay failed to check out.So we’ve got the CSRF middleware token, we have that street address, apartment address,country is up, same billing address, save info and payment method. And this could bethe payment option, because payment method is specified as the name. So let’s just comeback here. And I’m going to uncomment the form. And let’s just upload it again hereand make sure that we have the correct names for each input. So we’ve got street addressfor that. First one. And if we come down and inspect that one, we have street address.If we look at the payment option, here, for the radio options, we have name equals paymentoption. All right, so let’s come down here, all the way to these radio options. And thenthe name needs to be payment option. And then we’re going to test what the request lookslike when we submitted in this form. So let’s just refresh this. And we’ll just enter somedata there.And check out. Now let’s go back. And if we take a look here, so the query dictionaryis what we get here in the self dot request dot post. And there we can see all the fieldscoming through. And we get payment option is S. Now let’s go back and fill out thisform. Come back. And now you can see payment option is on. So that’s where the mistakeis, we need to make sure that the value that this payment option contains is either s orp not on. So that means back here, we can also comment that out.And if we just go downhere to the payment option choices, we can just add a value into the input. And thisis going to be that value variable that’s being looped through that we saw earlier waseither s or p. So now if we go back and refresh this, and let’s submit some data here. Nowit seems like it worked. And we see the form is valid. Cool. So that is working. Now, wecan come and get rid of all these print statements. And what we want to do is grab all of thosevalues that we saw here in the print statement. And we’re going to get them using the formcleaned data. And then we’re going to create a billing address. So we’ll just come hereto the models. And we’re going to create this model here. So we’ll say class billing addresscomes from models that model, we’re going to assign a user, and this is just going tobe a foreign key just like this user field is. And then we’re basically just going toadd all the values that this form has.So that’s street address. And that’s a characterfield will say maximum length is, let’s say 100. Then we have the apartment address, country,zip, and copy all of those, paste them there. And these two are both character fields, butthe country is not. So if we go back here to Django countries, we’re going to need toadd it as a field. So you can see here countries is a country field and it says multiple equalstrue, which we’re going to say it’s false. So we can just come here, like that, and makesure that we import this correctly as well. And that should be the same import, as wesaw here. So we’ll just go to the top, imported there, and the server still running. Cool.So now we have this billing address model. And I’m just going to say define string ofself.And I’ll just say return self dot user dot user name. And we are going to need tomake migrations. So we’ll run that and then run migrate. Then we can run the server Again.And so now when we submit this form, we’re going to want to create the billing addressfor this user. And then on the order, we’re going to need to create a field that referencesthe billing address, so that when we complete the order, we can then attach the billingaddress, to know where to send it, and also the shipping address. And then we’ll justadd billing address here and say, This is a foreign key to the billing address. Andwe’ll say on Delete equals to, let’s say, models dot set, no. And I’ll say, blank andno equal true as well. And then we can go back here, make migrations, migrate, and runthe server. And now here in the view, we’ll get all of that data.So that’s all of thesefields here on the form. So I’m just going to copy them all. And we’ll just paste themall here equals to form dot cleaned data, dot get, and then that value. So now we haveall of those values, we’re then going to import our model, which is the billing address. Solet’s come here and import that from top models. And then we’re going to say, the billing address,equals billing address. And here, we’re just going to pass in all of these values for themodel. So that’s user. So user equals to self dot request dot user, then we have streetaddress, and all of these street address equals street address, apartment address equals apartmentaddress.And we’ve got countries this isn’t, we were meant to set that to false. And we’llsay this is country. All right, make migrations to fix that. I’m just gonna say one, and alsoChina, and then migrate, and then just run server. Right, now we fix that. So then here,we can say that the country equals to the country.And we can say, zip equals zip, thenwe can say billing address dot save. And then we need to add the billing address to theorder here in the post request, we should actually check if the audit exists already.So let’s just come down. And I’ll basically copy all of this, there, and then just pastethat here. So we’re trying to get the order based on the user. And we can basically getrid of that context there. And if the object doesn’t exist, then we don’t have an order.So we just redirect them back. And I’ll say, go back to to the order summary, and everythingand paste that inside the try statement. just paste that there. So if the order exists,then we’ll check if the form submission was valid.And then we will take this order hereafter we’ve saved the billing address. And we’ll say order dot billing address, equalsbilling address, and then order dot save. And so now if this is a successful post request,then we also need to check which payment option was selected, and redirect the user to thatview that will handle that specific payment option. The same info that we’ve also gotten,and the same billing address, these are two slightly more advanced fields that we’re notgoing to do anything with just yet, so I’m going to comment them out. And above here,we’ll just say to do add functionality for these fields.And the implementation of theSave info is a little bit confusing, because in order for us to deliver something to thataddress, we’ll need to store the address. So it’s confusing as to how we could do thiswithout saving the information as we kind of needed to deliver that object to them.So if you have any proposals on how to handle that, leave a comment down below. Otherwise,we’re just going to leave it commented out for now. The same billing address which ismeant to be same shipping address. Let’s just come here, change this to same shipping address.And then here, this is same shipping address. Then here In the view, this would be sameshipping address, where we get the value of same shipping address.So if you are gettingthis value, then you’d want to create a shipping address model or we could just create an addressmodel and store a field on there, which would have a field saying his billing or his shipping,and then you could select which ones they are, or both of them. So there’s many wayswe can handle this. For now, I’m also going to leave that commented out and just workwith a billing address. And then here, after we save the order, what I’m going to do sayto do add a redirect to the selected payment option, which is something that we’ll handlein the next video. So in the last one, we ended off with our checkout view, we can goProceed to Checkout. And we worked on this form and many of the styling and handlingthe submission of this data. And we didn’t touch anything to do with this kind of promocode and displaying the items that are in the cart.And we will get to that in a separatevideo where we’ll talk about promotion codes, or discount codes and how to create those.But in this one, we’re going to continue with the payment method that was based on whatyou selected here in the form that you submitted. And we can view that view which is in coreviews, and that should be here in the checkout view. Once we submit the post request, wethen get all that data and some of the fields we weren’t addressing yet, but one of themis the payment option, which is something that we need to do here. Hence, we added thisto do which is to add a redirect to the selected payment option view where we’ll handle takingin that payment from the user.And so I’m just going to make another class based viewwhich will also inherit from the generic view. And I’ll just create it here, we’ll say thisis the payment view. And that’s just going to inherit from the default view, I’ll saydefine get takes in self ogs keyword dogs. And I’ll just say return a render of selfdot request.And we’ll say this is to payment, let’s say payment dot html. And I’ll bringthat into the URLs. And then I’ll say that the path goes to payment, I’ll say paymentviewed as view and say name is payment. And I’m also going to pass in kind of like a slug,which will be the slug of the payment option that was selected. So I’ll just put your paymentoption. And that could either be stripe or PayPal. And then here in the templates, we’regoing to need to create payment or HTML. And I’m going to take everything from the checkout,just paste it in there. And there’s a lot that we also don’t really need. So all I’mlooking for is this kind of container. And I’ll say this is payment, then we have therow. And we’ve got these two columns, I’m just going to get rid of that second columnthere. And in this first column, I’ll say it’s column medium 12. And then we have thiscard, I’ll keep that form that we’ll use.But the second form I’m going to get rid of,and then I’ll uncomment this year. And actually, I’m going to specify the class to have thatcard body like the other one. So if we go to slash, payment, slash stripe, right, andwe obviously don’t have any form that’s in our context variables. And I’ll just say thisis submit.But this entire form is actually going to be handled by stripe. So I’m goingto go search for the stripe docs. And I’m going to look for charges. And we’ll see you’recreating charges. And we should be able to see a form. And if we look for stripe j sand elements and scroll down, then this form here, I’m just going to inspect and actuallynot just bring us open a little bit. And so we’re basically looking for where this iframestarts, which you can see is right there. And if you copy that entire HTML element,you can come inside here and actually pretty much remove that entire form and you get awhole bunch of stuff. We get these iframes and I’m just gonna go down here. We’ll getrid of pretty much all the iframes the body the HTML, and we have this entire script tagas well, that I’ll cut out, put a tear at the bottom. And then we have the form, I’mjust going to tab that in, so it’s looking a little bit better, then the script has tostay there as well.And then the div wrapper, I’m actually going to remove and add endshere after the success token, which I’m also going to remove. So we just have that. Andthen we’ve got the head tag, I’m going to remove and this entire style tag, and a cutthat out. And all of this inside the script, I’m going to delete that gonna delete thatand the body tag. So everything’s inside this card, and then just come up top here, andwe’ll create a block. And we’ll just say this is the head links. And I’ll paste all thestyle in there.And if we take a look back here at base, that HTML, let’s just see ifwe have that block. And okay, that’s extra head. So just change that name. Okay, I’mgoing to get rid of crispy forms, tags. And we’ll get rid of the body and HTML stylesthere. Okay, so now we’ll have a form generated by stripe. So if we come back here, I’m goingto change this to be the stripe form row. And if we just come up here, we can get ridof the stripe token handler, and token handler hidden and the rapper as well as the token,so dot token, get rid of that. I’m gonna say this is stripe perform row. So let’s comeback and refresh this. And Alright, it looks a bit better. And I’ll change this to an IDof stripe form. So that if we come back here, this can be striped form.And instead of thisbeing label, I’m going to make this the stripe button label as an ID, then we can come down.And I’ll change this label to have an ID of stripe button label. And then for the button,I’m going to make this the stripe button and come down here to the button, I’ll give itan ID of stripe button. And we most likely would want to see the audit total like wedo here in this view. So what I’ll do is actually just grab this HTML, and then we’ll displaythe form here to make the payment. So let’s just go back here to check out. So I’ll makethis back to column eight. And so let’s just get rid of some of these. Okay, then we canclose that one. And we basically just want this entire column. Cool. So if we come back,and let’s go to payment slash stripe.Okay, let’s just see why this isn’t showing in theright way. So we’ve got that div there. There’s the form. And it looks like we have one toomany divs there. Let’s come back. All right, there we go. And I’m just going to minimizethat. And let’s open this app. And I’m thinking we can get rid of the promo code, but here.And what we’ll do is, we’ll make this one column that spans the entire width and justdisplay it on top of each other. Because the spacing is quite weird. So let’s just comeup here. And I’m going to make this column 12 and column 12. There we go. And this looksfine. So now we need to just handle what happens when you submit this payment.And if we inspectthis, we are getting this add event listener, add this line and that’s coming from line319 when we’re trying to add an event listener to the form. So that’s coming down here toget the element by ID of payment form. And we did change that to the the stripe form.So we got to come down here and change this to stripe form. Then we’re done. Have thisstripe token handler, we can get rid of that can get rid of that as well. Cool. So thatseems to be everything. Let’s just refresh this now. And, okay, we’ve got payment formthere as well.Try this again. And okay, cool. So now we need to go back here to the formand make sure that when we submit the form, that it’s posting this request to the rightURL, which is just going to be a dot. And that way, when we submit this, it’ll postit to this URL. So we can go here to the view. And we can define a POST method to handlethat request. So this will be self ogs, and keyword dogs. And then we can actually goand search for the stripe API, which slash Doc’s slash API, then I’m just goingto go here to charges. And then to create a charge, we’re going to need to bring allof this in. And I’m just going to paste this here at the top. And instead of outputting,that I’m going to say this comes from settings. So I’m going to say from Django con, importsettings, and this will be the stripe test key, or sorry, secret key, then we can takethis charge, come down, and we’ll just paste that over here.And we’re going to need tomake sure we get the token which is coming from the request. So this will be token equalsself dot request dot post, dot get. And that’s going to be that value that we add here instripe j s. So if you scroll down the stripe token, that’s the value we want to get asthe token. And then we can just paste the token there. And I’ll change this to USD.And the amount will be the amount of the current order. So the order we’re going to pass hereinto the context. So I’ll just say order there. And here, I’ll also say that the order equalsto order object start get where user equals self dot request dot user, and we orderedequals false, so we get the current order. And we’re going to want to get the total fromthat, because that’s how we’re going to pass the amount in. So that’s going to be orderdot get total.And then we have to say times by 100, because this value is in cents. Soif it’s $20. And we need to times by 100. So it’s 2000 cents. And the description, I’mactually just going to get rid of that now there’s a bit of logic that we need to thinkabout here. When we actually receive this post request. Not only do we need to createthe charge, but now we need to say that the order has been ordered. So we’re going tohave to change some of the values on the order model. So we’ll say here, that order dot orderedequals to true. And then we’re also going to want to keep track of the payments. Becauseright now, there’s no way that we’re keeping track of the actual stripe payment.And that’svery important. So we’re going to create its own class for that. So we’ll come down hereand say that this is a payment class, which comes from models that model. And I’m goingto specify the stripe charge ID as a character field. And I’ll make this a maximum lengthof let’s just say 30. Or rather 50. To be safe.I’ll pass a user, which will be a foreignkey to the user model. So that’s just going to be settings dot auth user model. And ondelete, I’m going to say equals two models dot set. No. And this is just so that we definitelydo not delete the payment if the user was deleted. And I’ll just say blank, and Nolatrue for that. I’ll say an amount equals two models dot float field. And we’ll add a timestamp.And say this is models that date time field. And I’ll say auto Now, add equals true.Andthen we can say define string of self. And I’m just going to say return self dot userdot username. And then this payment, we’re also going to under specify, like we did withthe billing address here on the order. So I’m actually just going to copy that entireline there. And this is going to be the payment which is going to be a foreign key with thepayment model that we just created. And I’ll leave all of this the same.So now here whenwe said ordered, ordered equals true, we also want to create this payment. And then we’regoing to assign the payment to the order. So first, let’s just save this. And we canalso see no module named stripe. So I’m going to say pip install stripe. And then I’ll sayPIP freeze into requirements dot txt.And then I’ll run Python make migrations.Cool, then I’ll say, migrate. And then we can run the server. Alright, so now we’regoing to create the payment. So I’m going to need to go to the top here and import thatmodel. So that’s the payment model. And then we can go back down. So here, we’ll say thatthe payment equals to a payment, we’ll say that the payment stripe charge ID is goingto be equal to the ID we get back from this creation here. So I’m going to say that chargeequals to that API call. And then I’ll come here and say, or we can access itlike this. Then I’ll say payment dot user equals self dot request dot user, I’ll saypayment dot amount, equals to this here, and I’m actually just going to specify her mtas its own variable, then then we can just say payment dot save. So now we have the payment,then we can assign the payment to the order. So I’ll actually bring that here as well.And then we can say order dot payment equals payment.And then say order dot save. Andwe’re also going to want to do some error handling here for this API call because thecard could fail and all the other types of errors. So you’re gonna want to just searchhere for stripe error handling. And we can just go to this first one handling errors.And then I’m going to select Python as the language. And I’m actually just going to copyall of that. And we can come in here. And I’m just going to create some space, pastethe soul here, and we can tab that in. So we’re going to try use stripes library, andI’m going to have to tab some stuff in here as well. Okay, so we’re going to try and dothe charge, which is what we’ll do here. And if we get a code error, then it’s declined.So what they’re doing is getting this message.And I’m going to basically do exactly thesame thing. So they’re saying error equals body, dot get error. And I’m going to cutthat out. And we can remove all of this. And I’m going to say messages, dot error, fromself dot request, and pass an F string, and just paste all of this in there, just likethat, then then you can handle the exceptions for the rest of these. So that being API connection,a stripe error, or just a general exception.And this is kind of the main one, becausethis means it’s something to do with you. So here, I would say we send an email to ourselves.Because this means you need to go and fix something in the code. And the rest of these,I’m basically just going to return an error as a message and just paste them all here.And get rid of all those past statements. And then they’ll just say, rate limit error.And here I’ll say, invalid parameters.I’ll say not authenticated, and then we can donetwork error. And then this last one for generic stripe error could just be somethingwent wrong. And they’ll say, you were not charged. Please try again. And then on thislast one here. I’ll say that this is a serious error occurred. We have been notified, somethinglike that. And then all of this here. We’re going to cut that out and bring that intothe try statement as well.So just like this So after we save the order, then we’re goingto redirect them back to some page. And this would probably be like a profile page or confirmedorder page. And I’m just going to say return redirect to let’s just say slash. And I’llsay messages dot success, parsing self dot request, and we’ll say your order was successful.And then we’re also going to want to redirect if these errors happen as well. So I’m justgoing to add a redirect for all of them. So what we should see happen is, when we testthis, now we’re going to create a charge, we should see that the payment is created.And we should see these parameters on the audit changed as well. And then the redirectshould be like the final confirmation that it worked.So we’ll come back in here, let’sjust refresh the page. And you can use stripes test card for payments, which is just fourto four to four times, and then make sure that the rest of the numbers have an expirationdate in the future. So now, if we submit the payment, Now, of course, we are getting aCSRF error. So let’s just add that in here in the form. Okay, I’ll just have to refreshthe page. Try again, we’re getting an invalid parameters error. And this could be becausewe’re not creating an integer value for the amount. So we need to make sure that we dothat. And actually, this order dot get total is the amount here that we should be savingon the payment.So I’m going to make sure we put that there. So servers running andlet’s go back to the cart, go to checkout. And okay, we’re going to need to go to paymentstripe. Okay, now submit the payment. There we go. Order was now successful. So let’sgo into the admin. And we’re going to need to bring our payment model here. So just importthat there. Cool. Let’s refresh this. Go to payments, admin. There’s the stripe chargeID, there’s the amount in dollars. And let’s go back to orders.Admin receive is the item,it’s now ordered. And there’s the payment. So now the payment is working. And we justneed to now make sure that when we submit the checkout form, so if I just add something,then now when we submit this form, and I select stripe, we need to make sure that here inthe view, and scroll up, we can then redirect based on the value of the payment option.And so instead of redirecting to core Checkout, what we’re going to do is check for the valueof the payment option.So we’ll say if the payment option equals s, and there are muchbetter ways to do this. But for simplicity, we’ll just keep it like this. So we’ll sayredirect to core payment. And then we need to pass in the payment option as the valuein the URL. So this and that’s going to be equal to stripe. And we’ll say, else if paymentoption equals to p, then it’s going to go to paypal. So we’ll say redirect to paypal.And then we’ll say else, we’ll show the message and return a redirect back to checkout andjust say invalid payment option selected.So all of that is working. We’ll come hereand just submit anything in here, and we’ll select stripe, click Continue. And we getredirected to the stripe payment form. And now let’s display this order here. So we cango back to the other view the payment view. And here we’re going to say that this orderequals that exact call there. And then we’ll say context equals to this dictionary andI’ll just say orders order and pass the context in there. Cool. Then back here, we’re goingto need to display some of them information. So here, this number three, this is goingto be ordered on items count.And then we have Have a list item of the product name,and it’s going through three times there. So I’m going to get rid of that. And we’llsay for item in order dot items, dot all. And then say in for. And in here, we’ll say,this is the item and double check the models here. So let’s just go back. So we’re referencingthe order items. So this should rather be called Order Item. And then we can say OrderItem dot item, dot title. And then this will be the description.So item dot description.And then this will be, I would say, the total price of that item. So if we come back hereto the order item, we can say get final price. So this will be Order Item, dot get finalprice. And let’s save that. And lastly, let’s output the order total. So if we come backhere, that’s going to be order dot get total. Cool. Let’s refresh this. Cool. So we havedummy item too. But I think it would be cooler if we had something like two times dummy itemtwo so that you know that you’re ordering to have that item. So let’s just go here tothe item title. And we’ll say Order Item dot quantity. And then just say x like that, coursenight and say, now you can see three times dummy item two, which is giving you 600.Andyou only have one item in your cart. So this seems to be pretty good. So far, we haven’tcovered the PayPal payment method, because there’s still a bunch of other things thatwe want to cover in this course. So for the time being, we’re just going to leave it athaving stripe as the only payment option. But it seems like everything is coming together.And in the next one, we can go back to this checkout view. And we’ll start handling promotionalcodes or discount codes. And actually, just as a last check, let’s just go back here tothe admin. And we’re going to look here at the orders, because now we have a new order.And then you can see the billing address was added to our user. So in this one, we’re goingto focus on adding discount codes to our checkout process, I’m just going to log in here, sowe can see where that’s coming through, we can just go to the cart, proceed to checkout.And here it is.And there’s one or two things that we also need to fix up. First, it’s here,if we just go to the home view, the list items of these products, they have the same image.And that’s because we don’t actually have an image field on our model at the moment.So let’s just go up top to this item. And I’m going to add models dot image field, whichwill be the image for that product. And we’re going to need to run pip install pillow sothat we can do this. Cool, then I’ll just say PIP freeze into requirements. And thenwe can run the server. Cool. So now, instead of rendering out this static image, we canthen go and output the image itself on the model. So I’m going to home dot html. Andwe can just go here to this image, just going to comment that out.And I’m going to createan image tag. And we’re going to need a source, which is just going to be item dot, and thisis image. So item dot image URL. And then I’m going to use the same class here. So justlike this, and then I’m going to take this URL, and I’m just going to download the image,then I can close this. And we’re going to go into the admin. And I’ll go to the items.And right we didn’t make migrations. So we can say manage that py make migrations. AndI’m just going to quit here so that we can add blank and null or true. Then I’ll makemigrations again. And then we could say migrate. Cool. Now we can run the server. Then we cango back here to the admin. And I’m just going to go to both items here and choose an image.Okay, now both of them have images and I’m going to go here and remove blank and nullas true and make migrations and I’m going to say ignore Now and migrates again.Therewe go, then we can run the server. Cool. So now let’s go to the home view. And they aren’toutputting. And that’s because the folder we’ve specified here for the media route isinheriting from the virtual environment path. And I’m going to change this to the base directory.And same thing for static route. And I’ll get rid of that. I’ll change this to mediaroute. And now I just moved the media directory back inside here, because it was one folderoutside the project. And then I’m just going to make sure that this is renamed media route.So now let’s go back, refresh this. And let’s just make sure that we get rid of that aswell. Okay, and they still aren’t displaying. So let’s just inspect here. And if we grabthat URL, paste that they see media is not actually a URL.So we’re going to need togo inside URLs here. I’m just going to go here to the top and just say from Django dotcon, dot URLs, dot static, import static. And I’m going to add a static URL to Settingsdot media URL, and say document route equals settings dot media route. Okay, let’s go backand refresh this now. There it is. And let’s go back. Okay, now that’s displaying. I’malso going to paste this, and we’ll change this one to static URL. And that’s the staticroute. Okay, cool. Now, if we go here to the cart, you can see that we have this item inthe cart, I’m going to go and open up the admin as well as we can see this in action.And I’m going to go to the orders. And actually one way of helping us distinguish which ordersare which, let’s just go into the core admin. And here, I’m going to say that this is theorder admin. And it’s going to come from admin, dot model admin. And I’ll just say that thelist display equals two, and just get the model here.So we have user, and then I’malso going to display the ordered field like this, then I’m just going to bring this inlike that. Let’s come back. Okay, there we go. So now we know which ones are orderedor not. So I’m going to go to the unordered. One. And we see that we have this item inthe order. And so let’s go and proceed to checkout.And just put in anything here, andwe’ll select stripe, continue to checkout, then just add a credit card and say submitpayment. Okay, now to successful, so we don’t have anything in the cart. That’s correct.But if we go back here to orders, that one is now ordered. And it shows that that itemis there. And it was the $200 item. So if I come back here and add this to cart, youcan see again, it still has that same price, the same quantity, which means it’s the sameorder item.So all we need to do is go on to our order item. And here we have the orderedfield. And we weren’t changing this value last time when we were submitting the payment.So let’s just go here to the view. And here when we were saving the order, we were sayingordered or ordered equals true. And we needed to do the same thing for all of the itemsin the order. So what I’m going to do here is just say that the order items equals toorder dot items, dot all. And because we have a query set, and we want to update all ofthese items, we can simply just call the update method on the query set. So we can say, orderitems dot update. And the field that we want to update is the ordered field.And we wantto set it equal to true. But then we need to loop through all of these order items andsave each order item as well. So we’re going to say for item in order items. Just callitem dot save and like this, we can then go and test this So let’s go and add this tocart. There it is. Proceed to Checkout, continue to checkout, submit payment. Now let’s gohere to the orders. There’s that third order, and we see ordered is true. Go to order items.Now we can see that order item has been ordered. So if we come here and go to the same itemand add to cart, now we see that it’s adding exactly one unique item. And that means wecan go back here. And now we have a new order item. Cool. So that is fixed. And now we canlook at creating discount codes.So what I’m going to do is in this file, we’regoing to create a new class. And this is going to be, let’s say a coupon comes from modelsdot model. And I’ll just say that the code is a character field. And we’ll say that themaximum length is 15 characters, and then just say define string of self. And we’llsay return self dot code. And we can bring this into the admin as well. And we’re goingto need to run, make migrations and then just say migrate. And then we can run the server.And so here, we can go back to coupons and add a coupon. And this is just going to beany code. So let’s say first timer, just save that. And then if we go here to the cart,and proceed to checkout, then here in this form, we’re going to enter that value, we’regoing to create a view that will handle taking in that code, check if the code exists. Ifit does, and the user hasn’t used it already.And we could do some other things to see like,does the coupon that the order has already give a higher percentage discount than theone you’re trying to add, we’re not going to add something like that. But that’s someideas that you could get creative with. And then just do basic validation, to add it ontothe cart. So let’s come back here, and we’ll go to the View, we’ll come all the way down.And we’re going to create a new view, and this is going to be add coupon, which willjust take in a request and a code. And so we’re going to want to get the user’s order.So let’s get all of this here.So we could actually just call dot get. And what we’lldo is we’ll just put it in our try statement. And we’ll just say except the object doesnot exist, which we already have imported from the top here. So if the object does notexist, then we’ll just return a redirect. And we could say that this goes to, let’ssay, core order summary. Or rather Checkout, and will display a message and just say, youdo not have an active order, which is fine. So if we do have that order, then we’re goingto check that the coupon code exists. So let’s go to the top and import the coupon. Thereit is. And then here, we’ll say that the coupon equals to coupon dot objects dot get wherecode equals to code.And we’re also catching the exception here. But let’s just definea shortcut method here. And we’ll just say, this is get coupon just takes a code. Andwe’ll do the same thing here. But we could wrap it in a try statement, and just pastethat right there. And if it doesn’t exist, then we’ll just say, this also takes in arequest maybe, and we’ll say, this coupon does not exist.And then here, we can saya coupon equals to get coupon where the request is the request, and the code is a code we’rebeing passed in here. And then here, we just need to make sure to return that coupon. Sonow we have the coupon. And then we want to somehow assign this coupon to the order. Soagain, on the order, we’re going to need to create a foreign key field to the coupon.So we’ll say coupon equals models dot foreign key to the coupon and all of this same stuffand we’re going to need to Make migrations for that.So make migrations and migrate,run the server. So now, we can then assign this coupon to the order. So we can say ordercoupon equals two, we could actually just do like this get coupon. And then we say orderdot Save, and then return a redirect back to checkout. And we’ll just put a successmessage. And we’ll say, successfully added coupon. We’re also not doing any kind of validationright now, in terms of how many times this coupon has been used. Or if you’ve used thiscoupon before, as well, those are some things that we need to take into consideration. Butfor now, let’s just take this add coupon and bring it into our URLs.And here, I’ll justcopy that and say this is add coupon. And we’ll put code in there. And then just saythis name of the URL is add coupon like that. So now we have a URL, and back inside theorder summary dot html, we can then go down to that form. And then down in the checkoutdot html, we should have this form here. And this exact column medium four is the exactsame thing that we used in the payment dot html. If we just come up here, you can seethere, I’m going to get rid of that comment there.So what I’m going to do is I’m goingto cut that out. And I’m going to create a snippet. And we’ll just say that this is theorder snippet dot html. And I’m just going to paste all of this. And then we can justbring this in a little bit. So we need to make sure that we are passing an order intothis order snippet. And we’ll also need to pass any coupon codes that we’ve added, we’llworry about this in a second. Let’s just come back here. And we’ll say include the ordersnippet dot html. And because this used to be here, we don’t need to use the width keyword.So if we come back and refresh this, and this is the wrong view, let’s just go here to payment,and stripe. Cool. So you can see that that’s still working. So now we want that exact samething to be used here. So inside Checkout, we can pretty much remove the entire column,except we want to make sure that we keep this form.So I’m going to cut it out and bringit into the order snippet. And we’ll just paste it right here. And it actually goesinside this div. So like this. But now if we were to come back and just refresh thisnow you can see that we have promo code here. And if we don’t want to display it here, wecan put in some logic to do that as well. But we’ll just leave it for now. So back insideCheckout, we can then go and remove the entire div. So this here, everything inside there.Just delete all of this, and say include the order snippet dot html, then let’s go back,refresh this.And there it is, we obviously aren’t bringing the order into this ordersnippet. And if we check here, for any context variables, we can see we only have a formdisplaying and a lot of comments, so I’m going to clean this up as well. Okay, that’s muchbetter. So we need to make sure that we bring the order into the checkout view.And if wescroll up, then here is the checkout view. And so here in the get, we’re going to wantto pass in the order. So let’s just put order like this. And we’ll use the same logic wedid down here. To try and get the order. I’m just going to copy all of that. Come up tophere and use a try again. So we’re getting the order and then we don’t need the couponor any of that. And this is self dot request dot user. And then say self dot, actually,we don’t need that message. And we don’t need that return there either. We can basicallyjust cut that out, put them inside the try statement. And make sure that this is selfdot request. And then the order is that order. So we’re trying to get the order, if the orderdoesn’t exist, then we will return the exact same redirect to the checkout view and justdisplay the message.Otherwise, we’re passing in the form and the order into the context.So now if we come back, and let’s just see, run the server and refresh this. And there’sour order coming through now. So let’s now go to the audit snippet. And we’re going todeal with this form. Now, we need to make sure that when we submit this form, that itgets posted to the correct URL. And actually, instead of doing it, how we have it here,I’m going to remove this code there. And back inside the view, I’m gonna remove that codeas well, I’m going to create a form. And this is going to be the coupon form, which willjust be forms dot form. And all it takes is a code, which is going to be a character field.And if we take a look at the snippet, we need to make sure that the input has a class ofform control.So let’s take all of that, come here. And we’ll say widget equals forms thattext input and say attributes where the class is form control, and the placeholder is promocode. And then we can also add the two fields here. Okay, so all of that, then we can bringthis coupon into the views. So from dot forms, import coupon form. And then all the way downhere. We’re gonna say if request, dot method equals post, all say form equals coupon form,with request dot post, or none. And then say, if valid, then we will do all of this,let’s just get rid of that.And otherwise, we’ll return some kind of air, I’m just goingto return none there for now. And I’ll just put to do res error. So we’re only acceptingPOST requests. And then here, in the try statement, we’ll say that the code equals to form thatcleaned data dot get the code so that we can then pass it into the get coupon. And yes,you could also validate this on the form, there’s many ways you can do this. And sothen here, instead of outputting, the input like this, I’m going to comment it out. Andhere, I’m going to say, form. And back here inside the view, we’ll go up to that checkoutview up top here, I’ll add coupon form as the coupon form, like this, and then justcome back here. And let’s change this to coupon form. And I’m going to access DOD code, becausethat’s the only field there. So now, if we come back and refresh this, that still seemsto be working, let’s just inspect here.And we can see that the name equals code. So that’slooking good. And then here, the type button, I’m going to change to type submit, and alsoadd the CSRF token. And we need to also add the action, which is going to go to that URL.So it’s going to be URL to core. And this is going to be add coupon to a posting tothe Add coupon URL. Let’s come back and refresh this now. And if we take a look here, we havefirst timer. So if we submit first timer, let’s just come back into the view and doublecheck what’s going to happen. So it’s going to get the code, we’re going to check forthe order. We’re going to get the coupon, save it to the order, and then we’ll see successfullyadded coupon.And it’ll redirect us back to this checkout. So let’s redeem. And we’regetting this didn’t return HTTP, which means that we didn’t specify method equals post.So it was sending a get request. And let’s come back and refresh this. Just get rid ofall of that. Go to proceed to checkout Add first timer redeem their successfully addedcoupon. Now if we go back to the order, go to that last order, there we can see the couponis attached. And now we want to add a method that will subtract the amount that the coupongives a discount for. So let’s go back here to the model. And here on the order in theget total method, after we loop through all the items, we’re going to subtract the valueon the coupon. So if we come back here, we need an amount on the coupon. So that’s goingto be a float field.And then the amount here, we will say, total minus equals two. And it’sgoing to be self dot coupon, dot amount. And then we’re going to need to make migrations.So I’m going to provide a default. And let’s just say that this is 20. And then we canmigrate, run the server. So if we come back here, now the total is 180. And the promocode, we’re going to display the name of it, and then the amount over there.So let’s goback to order snippet. So now since the coupon is attached to the order, we can access itvia that order. So I’m just going to say order dot coupon, because of the foreign key. Andthis is going to be code. And then for this $5, we’ll replace that with ordered couponamount. And there we see first timer we see minus 20.And there’s the 180 total. So allof that looking good. If I go to slash payment, slash stripe, we can see it’s working hereas well. And what I’m going to do here in this payment view, you can just go back hereto views and just scroll up here to the get method of the payment view. I’m going to setdisplay, coupon form as false. And then I’m going to copy that. And we’re going to bringit here into the get method of the checkout view pasted here. And I’m going to make thistrue, then inside order snippet, let’s actually grab this value, we can then say if displaycoupon form. And and if. So if we come back here, now we don’t see the coupon form.Thisis optional, if you want to handle it like this. And so let’s just go back here to thecart, proceed to checkout. And okay, there it is. And one thing that we also saw is thatwe were able to go to the payment view without completing the checkout form. So we want toadd some kind of condition that’s saying something like, if you don’t have a billing address,then you can’t go to the payment view yet.So let’s go to here to the payment view. Andwe’re just going to check your if order dot and we can come here to billing address. Soif audit our billing address, then we will render out this request. And we’ll say else,then we will grab something like that. And just say you have not added a billing address.And we’ll redirect back to checkout. So now if we just go back here to this order, youcan see that it’s not ordered yet. So we can see we don’t have a billing address here.So that means that if I were to go to payment, slash stripe, then it just says you have notadded a billing address.Let’s just refresh that there. And it seems messages dot errordoesn’t work. So let’s use warning instead. And instead there as well. And we’ll justreplace it like this. So messages dot error with messages dot warning. There we go. Andthen if we just come down here to the bottom, we have this to do over here. And insteadof checking if the request method is a post, I’m just going to change it into a class basedview. And we’ll call it the Add coupon view. And again, it’s going to take in a view andthen we’ll just say define the post request, which takes ogs and keyword dogs, and thenwe can get rid of request dot post there, get rid of that and just pass in self dotrequest instead of request.And then we can just make sure that our URL uses this correctly.So we view and change the input there as well run the server and a little spellingerror there. Okay, cool. So now we won’t be able to send a get request to this view. Andwe also won’t be able to go to the payment view without having a billing address first.So let’s try and complete the process and make sure that everything’s working. And wemost likely also would want to show the discount here in the order summary.So we got up tothe order summary view, which is here, we’re already passing in the order. So that meansthat we can display the coupon if there is one. So let’s open up the templates, we’llgo to order summary. And if we scroll down, here we have if ordered dot get total, thenwe’re displaying the total. So what I’m going to do is add another condition and say iforder dot coupon, then we’ll display another row as well and just say endif. So I’ll copythat row there. And I’ll say, coupon. and the value will be object, dot coupon, dotamount. And I’m also going to change that to object dot coupon. So if we come here andrefresh this, now we have coupon there.And I’ll also put a negative in front of that.Cool. So that’s displaying there, proceed to checkout. And we’ll just add an addresshere. Select the country, select stripe and just enter the stripe card number, submitpayment. Order was successful. Let’s go here, refresh it, there’s the billing address andthe payment, it’s now been ordered. And let’s go check the payment value. And the amountis 180. So everything seems to be working pretty well. So in this video, we’re goingto be focusing on creating kind of like an order management system. And this is to helpus kind of understand where all of our orders are in their phases. And an example of thatwould be keeping track of the number of orders that have been abandoned. And how many ofthem have been delivered, how many of them have been paid, received, etc. So we’re goingto add a whole bunch of statuses here on our order model.And that’s going to help us keeptrack of those. So I’m just going to come here and add a couple more fields. And thisis going to represent kind of like the lifecycle of an order. Now, I’m actually just goingto add it as a comment. Firstly, so we can brainstorm this. So the first phase wouldbe when the order is created, this is when someone actually adds an item to their cart.And that is the beginning of the order. So that is we’ll just say item added to cart.Then the second phase, we also saw this in our checkout process, if we just log in hereto demonstrate. If I come here and add something to the cart, and we’re getting this none typeobject has no amount. Let’s just see here. This is total minus equals self dot coupondot amount, which is in my 95. So this is over here. And we should actually just adda condition to check if there is a coupon. So we’ll say if self dot coupon, then we’llsubtract that amount. And now let’s go and try this again.There we go to get rid ofone there. So this is the first step, we’ve added an item to the cart. Now if we proceedto checkout, we would fill in this form and it would add the billing address to the order.And that is the second phase. So adding a billing address, then we know that if we fillthis in, and I’m just going to put something in there, select stripe continue. We knowthat this is the third phase, and oh, we’re getting a promo code thing there. But thereis no promo code. So let’s go fix that as well. So inside templates, and this is payment,and it’s included in the order snippet. So here, I’m just going to add if order a coupon.And and if I can, let’s try that now.There we go. So here, we would fill in the payment.And let’s do that, and then submit the payment. And I’m getting not authenticated, that meansthat I don’t have my stripe keys in. So I’m going to go add that. So let me go and trycheckout again. And that could actually be another status that we add here in the model,which is a failed transaction. And this is actually something you can listen for withstripe web hooks. So I’m going to put your failed checkout. And this could be due tomany reasons which we saw we covered in the exceptions.So we could keep track of howmany of each exception has occurred. And you’d most likely be more concerned with the errorsthat are due to your part not due to stripes API, for example, receiving too many requests,you’d rather be focused on why your code didn’t work. And hopefully, that doesn’t happen toomany times. So let’s go proceed and continue submit payment, cool order was successful.And let’s open up the admin. Go to the order. There’s that last one. And so that confirmsthe third process, which is payment, then, once it has been bought, because this is ecommercemeans we actually have to deliver that item that they’ve bought to their address.So dependingon whatever business processes you have, there’s a lot that could be put in here, such as somethinglike pre packaging, packaging, processing, and the whole supply chain movement there.And we could add this in house or something like pre processing, processing, packaging,etc. And I think the most important takeaway from that is when it’s ready to be delivered,or is being delivered. So basically just keeping track of the orders that are on the road.So we’ll say being delivered as a status of the order. And then logically from there,once it’s on the road, and it’s heading towards the customer, the next step is to note whenit’s been received. And if you’re using DHL, or FedEx or whoever you’re using to deliverthat.Normally, you do have some process with the person who’s receiving it has to signit off and say that they’ve actually received this item. And you’ll want to keep track ofthat in whichever system that is that you’re using, and link that to here. So once it hasbeen received, you can then confirm that it has been received here. And this may seemlike the last step, but we actually will need to keep track of the number of refunds. Andthis is actually the last step, because there’s no way it can go after it’s being refunded.So we definitely do want to make sure we keep track of this because it does happen, peopleasked for refunds.And we want to make sure that we have functionality to handle that.So what we’re going to do is add these three statuses here on the model, and they’re justgoing to be Boolean fields. And by default, it’s going to be false like the ordered field.So I’m just going to paste that there. So the first one here will be being delivered,and by default is false, then we have received, and how we’ll handle refunds is just by addingtwo statuses here. And this is going to be refund requested. So that means someone hasactually either sent an email or completed a form explaining why they are requestingthe refund.And then we would have refund, granted. So there would also be this Booleanfield. And you could keep track of the number of refunds rejected. But if you have thesetwo already, then you don’t really need to. So the whole point of this is so that youcan keep track of what has been processed in terms of refunds and what hasn’t, and stillneeds to be processed. So once something has been granted a refund, then it’s kind of movedover to a separate pile, you don’t need to worry about that anymore. But the refund requeststhat is an important field that we should monitor. So with all of these statuses added,we’re going to make migrations. And we’re then going to add some stuff here in the adminto help us manage all of these fields.So we’ll say Python, make migrations,then we can say migrate. And then I’ll go and run the server. And so we have our orderhere inside the admin and we already started creating our own custom order admin. And we’regoing to build on top of this now. So let’s come back inside here, and start off herewith the list view or list to display and we’re going to add Whole bunch of these fieldsinto the list display. So let’s take a look here back at the fields that we’ve added.And that is being delivered, received, refund requested and refund granted. And we’re goingto add all of them in here. So just like this. Now, let’s come back in here and refresh this.And this kind of gives you an idea of the whole workflow. It’s ordered, hasn’t beendelivered. And again, you could add in pre processing, packaging, etc, being delivered,received, refunds requested and refund granted. And so we’ll customize the admin to allowto filter by these fields.And there’s one more important field that we definitely needto add on to these orders. And that’s a reference code. Because without a reference code, there’sno way for the user to actually communicate on which order it is, we’re going to get tothat in a second, but let’s just customize the admin here. So back inside, here, we havethe list display. Next is going to be the list filter, which is also going to be a listof fields. And I’m basically just going to copy all of these, I can come back in hereand refresh this. And now you can see the filter here on the right hand side. So youcan filter them for which have been ordered, which have been delivered, and etc. So whatI’m going to do is copy these three, we’re going to go back in the admin. And we’re goingto add the list display links, which is also a list of fields, we’re going to add thatand we’re also going to add the user. Now we get some errors, because these fields arenot inside our list display, so we need to add them in here as well.So I’ll add it.Okay, cool. Now, let’s come back in Yeah, this just allows us to navigate to these billingaddresses, and the payments, all from this one view. And so now let’s go and add thereference code. So let’s just add it here at the top. And this is going to be a characterfield, I’ll say maximum length is, let’s say 30. Or, actually, let’s go with 20. And thenwe can go and make migrations, we’ll add a default and just say 123. And then we canmigrate, run the server again. And so here inside our views, we’re going to add a functionthat will create that reference code.And the moment we create the reference code isonce the order has been purchased. So that’s going to be here in this payment view. Soif we come a little bit down here inside the try statement, when we assign the paymenthere, we’re going to assign the reference code. And I’m just going to go all the wayto the top of this file here.I’m going to say define create reference code, which doesn’ttake any arguments. And here we’re going to need random and we’re going to need the stringpackage as well. So I’m going to say import random and import string. And then here, we’regoing to say return an empty string. And I’m going to say dot join on random dot choices.And here we pass in a list of choices. And this is just going to be string dot ASC II,lowercase. And I’m going to add string dot digits. So that’s just going to create a randomsequence of characters. And then I’m going to pass in K, which is a special argumentfor the length of the string, which I’m going to say is 20. And then we’ll bring this methoddown here to our to do, and I’ll say order dot reference code equals create referencecode. So now we’re going to go and test this out. So I’ll come and add this item to thecart, Proceed to Checkout, continue, and submit payment.Now let’s go back here, refresh this,we have a new order course. So there’s the reference code, we can see there. And we’lldesign a simple profile view that shows you all of your orders so that you can at leastsee the reference code as well. And then that way, when you want to ask for a refund, youcan reference that code and we know what you’re talking about. So back here in the admin,we’re going to want to add a search field here.And this is search fields actually,which is a list of fields that we can search by, I’m going to add the user so that we cansearch by user. And I’m going to add reference code so we can search by reference code. Andthese are really the only two fields that we should be searching for. So like this,we come back into the admin and just go back to the list display. Now we have a searchfield And if I go back here, and we searched by this reference code, and we’re gettingrelated field got invalid lookup.So here, I’m going to change this to use a user name.And if you search for it, now it works. So we weren’t searching a field, we were searchingan object. And I’m not going to display the reference code here. Because it doesn’t reallyprovide you with any value, you should just be able to rely on the search. And then ifyou click here, then at least you can verify that it has that reference code.So now wecan at least see and work with our orders in a much better way. And we can go and adda form for users to fill in, so that they can request refunds. And then what we’ll dois we will change the status of the order to have a refund requested as true. So let’sclose all of this.And all the way here at the bottom, we’re going to add a new view,I’m going to say this is the request refund view, which will inherit from the defaultclass based view, I’ll say define the POST method. And then we’re going to need a form.So here beneath the coupon form, I’ll say this is the refund form, which just comesfrom forms diet. And this will just be a normal form, I’m going to say that the referencecode equals to form start character field, and we could add a message as a text area,then we can take the form. And let’s just go to the top to import this, then we’ll goback down. And here we’re going to say our form equals to refund form of request or postor say, if form that is valid, then I’m going to grab these two fields, the reference codeand the message, we can paste them here.And I’m going to say equals to form dot cleaneddata dot get that value. And what we could also do is define our own refund model. Andthis is just to store the refund so that we have record of it. So we can do this verysimply, I’ll just come down here. And I’ll say class, refund model stock model, I’llspecify the order, which is a foreign key to the order and just say on the lead equalsmodels dot cascade, will provide the reason, which can just be a text field, let’s say,then we’ll have accepted which can just be a Boolean field.And I’ll say default, equalsfalse. Because when we created, it’ll be when the user has submitted that form, which meansthat it obviously hasn’t been accepted yet. And then we can just say, define string ofself. And we’ll say return self dot. And I’m just going to return the primary key, butwe’re going to need to put this inside an F string, because it’s an ID, it’s not a nota string. And then we can bring this refund into the admin as well. So for there, andwe can also bring it here inside our views. So import this model. And so we’re first goingto try and get the order by this reference code field. So we’re gonna say try, orderequals to order dot objects. dot get where the reference code equals to the referencecode. Then if we do have that order, we can say, order dot. And let’s just go back uphere.So order dot refund requested, equals to true order dot save. And then we will storeour own custom refund. So we’ll say refund equals to a refund object, or say the orderequals to the order will say refund dot reason equals to message and then we can save therefund. And we actually would also want to keep track of the email from the person whosubmitted it. This is just so that we can get in contact with them. So we’ll say modelsdot email field. And then here we can say in the form that we have an email which isan email field. And then we will get the email just like this. And I’m going to change thatto self dot request dot post. And then here we’ll say refund dot email equals to email.Now we need to go and make migrations.So we’ll say make migrations. And up. Let’s justfinish here, what we what we started. So we’ll say accept object does not exist, we’ll justreturn a redirect back to that same view, I’m just going to put slash for now. And I’malso going to add a message and just say, messages dot info, with self dot request.And we’ll say this order does not exist. And that’s just tablet in there. And then we canalso redirect here. And we’ll say, messages dot info. And we’ll say your request was received.And now we can try and make migrations. There we go. Now we can migrate and run the server.And then we can bring our refund view into the URLs. And I’ll just add another one here,we’ll say path to her request, refund, and say view.And we can say, name, equalsrequest, refund, then here, in our view, when we redirect back, we can redirect back tocall request refund. And we can do the same thing there. Cool. So now we need to go andbuild this form in HTML. So let’s go into the templates, create a file there, this willbe request, refund dot html, I’m going to go here to the order summary, I’ll just copyall of this, and we don’t need a table. I’ll just put your request, refund. And then here,we’re going to create a form, I’ll pass in the CSRF token.And I’ll say that the methodequals post. And I’ll just output the form here. And I’m going to say crispy. And thenhere we can say load crispy forms tags. And then I’ll add a button and just say Submit.And the type is going to be Submit. And the class is going to be button button primary.And then we need to link this to our view. So here I’ll say define get, which just takesin self. And I’ll just say return a render of that request. And it’s going to go to requestrefund dot html, then I’m going to say the form equals to this refund form. And we canget rid of all of that. And we’ll bring this into our context, we’ll say form is form,and then pass the context in there. And then just say, self dot request there. Okay. Now,let’s go to request, refund. There’s our form. And let’s go back into the forms. This shouldbe a character field, and say widget equals forms dot text area. refresh this, there wego. I’m just gonna specify here that the attributes were the rose is for just refresh that.Therewe go. Alright, so if I enter just a random thing in there, and say add to model com,submit, this order does not exist. Cool. Now, let’s go back here. And I’m just going tograb this reference code, paste that in there. And say, submit, your request was received.Come back in here, refresh this. Now we see refund requested. And so lastly, we’re goingto add our own custom action. So you see how these are actions, we’re going to create ourown custom one, so that we can select the orders, however many we want, and then wewill update the status from requested to granted. And you could add the same functionality thenfor the rest of these, but we’re just going to demonstrate it with this one field.Sowe need to go back inside the admin. So I’m going to close all of these and just openup the admin. And so we’re going to just define our function here above this class. And I’mgoing to say that it’s called make refund. accepted. And this takes in a model admin,a request, and the query set as arguments.And so here, because we’re passing in thequery set, this is where you can make use of the query set dot update method. And allyou do inside this method is just specify the field that you want to update. So in ourcase, we’re going to update the refund requested field to be false, because it’s no longerrequested, it’s now accepted. So I’m going to say that, and I’m going to say refund granted,equals to true. And that’s it, then we can just add a description. So I’m going to saymake, make refund accepted dot short description, equals to.And we can get an idea from here.So delete selected orders, this will be update orders to refund granted. And then we canjust take this, and we bring it into the actions, which is a list of functions created in thisformat. So now we have our own custom action, we can refresh the page. And now you can seehere, update orders to refund granted. So if I grab this one, select that and clickGo. Now you can see a change the status from requested to granted. Alright, so in thisone, we are going to start working with a default setting for our shipping and billingaddresses. So this will basically allow you to click a checkbox, which can then save yourcurrent billing information that you entered into the form as your default billing address,which you can then reuse in further checkout processes.And the same thing for the shippingaddress. And I’m just going to go and login so we can see what we’re actually talkingabout. And let’s just go and add something into the cart. and proceed to checkout. Andso right now this is the checkout form, we have some options that we can fill in forthe address. And then we can click here to say that the shipping address is the sameas the billing address.Now we’re going to change the way that this looks a little bitand just add like a heading here that says that this is the shipping address part. Andthen we’ll have the billing address part and add in some extra checkboxes that can allowyou to basically specify whether you want to use them as the same address or you wantto reuse old addresses. So things like that. So that’s what we’re going to do. So let’sjust go and get the code here. So we’re going to call into views. And let’s just installthat. And so we want to go here to the checkout view. And here inside the post request wehad a to do, which was to add some functionality for what we’re talking about right now, whichis the whole same shipping address and saving this information. But we’re going to changethe way that this works in the models. So a lot of this is going to change. So let’sjust open up the models here as well. And we’ll just go here to the address. And let’sjust see here, this is the billing address.So right now we only have one kind of address,which is the billing address. But what we’re going to do is change this to be just a genericaddress. And then we will add a type of address here as one of the fields. So we’ll say thisis the address type, and say this is a character field. And I’ll say that the maximum lengthis one and then we can add choices, which can just be another tupple up top here. I’mjust going to copy and paste this, like that. And we’ll just call this the address choices,then this is either going to be billing or shipping.So we can just get rid of that lastone. And we’ll call this the shipping. And we’ll call this billing. So then we can takethose and just come down and specify those as the choices over here. Cool. So now wehave that we’re just going to add one more field and this is default. And this is goingto be a Boolean field. So we’ll set default equal to false, so that it’s not a defaultaddress. Basically what we’ll do with this field is every time you say use this as mydefault billing address, or use this as my default shipping address, will then just grabthe address you just created and then set default to be true, which you can then selectin further purchases.So that’s what this field is going to allow us to do. But nowthat we’ve changed the address, we’re going to need to change This here and our orderswell, because we have a foreign key to that, that model already. So I’m going to changethis to be called address. And then we can actually just copy the entire thing. And we’llcall this one, the shipping address. So let’s just change one of them here. But becausethe foreign keys on the same model, we’re going to need to give them a related name.So this one can be called the shipping address, just like this. And then the same concepthere for the billing address. Cool. So now let’s try and make migrations with that. Andnow we’re getting an import error in our views.So let’s just go here to the top line 11.So this is no longer billing address. And I’m just going to search for all of thosebilling addresses. And there’s only one other which is there. So we can change this to becalled address. And then for this one here, we’ll also call this one address. And whenwe create a billing address, we’ll just need to come here and specify that the addresstype is equal to b for billing. So let’s try and make migrations again.And there we go.Now we can migrate. And now we’re getting an integrity error. So the easiest way tosolve this is just for us to go and delete those migrations. So I’m going to delete thatentire folder, and then delete the database as well. Then we can say, managed up py makemigrations, just for the core app. And then we can say migrate, okay, also create a newsuper user. And then we can run the server call, let’s go into the admin.And we’ll justimport that model. So address. And here we have billing address, we also going to addin the shipping address. So just specify that here. And then we’ll also add it in over herein the list display links. Okay, then we can just copy this and register the address model.And if we just take a look here, again, we’re just going to copy all these fields, so thatwe can specify them in a custom admin model. So we’ll come here, also, this is the addressadmin, which inherits from the admin dot model admin, then we’ll just say list display isall of these fields. Okay, then we can also add in the list filter. And we can filterby the country, we can filter, if it’s a default address, and we can filter by the addresstype. And we’ll probably want to put country at the end day because it’s quite a long list.So let’s just move it there.Then we have the search fields. And we’re going to wantto search by user. And we could add all of these fields in as well. So let’s just addthem in here. So street address, the apartment address. And we could also search by zip aswell. Okay, there we go, then we can just take that, and make sure that we registerthe admin with that model for so if we go into the admin, and we’re going to need tolog in with our new super user. There we go. And we can also come here and change the classmeta. So let’s just add class matter. And we’ll just say verbose, name, plural equalstwo addresses. Okay, then that’s just a refresher. And there we go, that looks better. So wecan come in here and we can add an address for user. And we’re also going to need tochange the form now, because if we come into the checkout form, you can see that this isall based on having one type of address which is the billing address.So basically, whatwe want to do is duplicate all of these fields because our form is now going to have a billingaddress and a shipping address. So to make this easier, instead of putting all of thesefields over here, we’re just going to do it in place. HTML. So let’s just keep this openand go into templates. And we can go into checkout dot html. And just here above theaddress, I’m going to add an h3 tag.And we can just say that this is the shipping address.That will take in first. And then what I’m going to do is wrap all of these fields exceptfor one of the last ones. And we’ll just wrap it all inside a div. So all of this all theway here to this HR, I’m just going to tab that in, close that off in a div. And I’mgoing to give it a class name. And we’ll just say that this class is the high double shippingform. This is just so that we can get hold of it to toggle the display from being displayedto not being displayed depending on whether we click a checkbox. And then I’m going tobasically copy all of this. So everything up top beneath this HR or just above the HR,I’m going to then paste it all again, except this one is now the billing address. So ifwe were to come back here and refresh this, we’re getting redirected to many times. Solet’s just go back here. And what I’m going to do is just come here and add in a new item,just so we can add something to the cart.Cool. So now we have an item. And there itis. So we can go and visit it Add To Cart. Here it is. And let’s proceed to checkout.Cool. So now we have shipping address, billing address. And we’ve got the payment processover here. So we can actually add that as a heading there as well. So if we just comedown here, after the HR tag, what I’m actually going to do is move the div to not includethat HR. And I’ll do the same thing with this wrapping div over there. So now if we comeback here, this is continue to checkout.And here’s our radio options for the payment option.So here, I’ll just add another h3 and we can just say this is payment option. Now if wetake a look. And there we go. And we’ll fix the styling as we go along. But for now, let’sjust go back here into the form. And let’s just get all of these placeholders and movethem over as inputs here in the form. Because right now we are putting these form fieldsdynamically. So what I’m going to do is just get rid of that. And then we can come hereand specify an input, I’ll set the type is text, we can set up the placeholder is equalto this value here.So I’ll just copy and paste that in there, we can set that the IDis going to go to the shipping address. And we can say that the name is also the shippingaddress. And then we can say that the class is form control, then we just make sure thatthis ID is the same as that ID. And then we will basically do the exact same thing here.So we’ll just get rid of that output there. And I’m just going to call this shipping addresstoo. And then get rid of all of that and change that as well. And then the placeholder canbe what the placeholder is over here. So apartment, or suite, okay, then the form country, we’regoing to output the way it is because that’s coming from our Django country’s package.So we’ll leave it as it is. But we can actually get rid of the widgets here now. So we’lljust get rid of all of that. And then I’m going to add in your required equals false.And even though it is we’ll handle whether or not we got it in the view, and then I’mgoing to change the names of those as well.So the first one is the shipping address,then its shipping address to country, we’ll change to shipping country. And then for thezip, we’ll change this to be shipping zip as well. And same thing, I’m going to getrid of all of those and just add the required equals false, then shippings up, we can comedown and here instead of this form that’s being outputted. I’ll copy that and pastethat here. Then we can say that this placeholder is let’s just say so code, and then shippingzip, we’ll copy and paste as the ID and the name and there we go. Then also change theforward to be shipping. So as well. So if we take a look, we just have that countrynot showing up. So let’s just come back here, copy shipping country come back here, andthis is formed that shipping country. Then if we come back and refresh this, there wego.And I’ll just fix some of the spacing here. And so we can see that this high leveldiv is wrapping all of that over there. But what I’m going to do is I’m going to cut bothof these out, and I’m going to move them inside there as well. And then there’s just tab thatlike this, then I’m going to get rid of all these if statements inside these inputs forthe checkboxes, we can keep this one as same billing address. And I’m just going to changethe ID to be same billing address and same billing address. And we can say here, thisis billing address is the same as my shipping address. So like this. So that’s going tobe the first checkbox, then the second checkbox is going to be saving this as the defaultshipping address. So we can just come here and change this text and say, save as defaultshipping address. And then the name, I’m going to say as set default shipping. And we canthen just copy and paste this everywhere it needs to be. Okay, now let’s kind of refresher.Cool.So that’s looking much better. Then there’s one more checkbox, we want to addhere, which is to say, use the default billing address. And then we could put some text that’sreferencing your current default billing address. So I’m basically just going to copy this,come outside the high level div. And we’ll put this one here. And then say, instead ofSave as this will be use default shipping address. And here, we could just put that,say, some address like this. And instead of set default, it will be used a default. Andmake sure we use that everywhere as well. So if we come back, the idea here is thatif we select to use the default shipping address, then all of this will be hidden. And that’sbased on a toggle. So if you toggle this, all of this will hide or show, which we’lljust do with jQuery.And we can also come back into the form and make sure that thiscountry field has required equal false as well, in the case that you use a default address,then we can come back here and basically do the exact same thing for the billing address.So what I’m going to do is also make sure these labels are correct. So let’s just grabthe same billing address. So same billing address. And this should actually be sameshipping address. And social these, then we have set default shipping. So I’ll just pastethat one here. And this is also going to be a Boolean field. And then the last one hereis use default shipping. And we can get rid of that save info there. And all of thesefields that we used for the shipping form, we can come here and paste them all again,and just call all of these, the billing equivalent. So like this, and we can actually just cutthese three out and move them below. So like this.And just like we’ll have set defaultshipping and use default shipping, we’re going to have the exact same thing for the billingequivalent. So this will be set default billing and set default or use default billing. Sojust like this, and then we can come back here, go to the billing address. And I’m justgoing to copy all of those inputs that we just created here into the billing addressform. Okay, there we go. So now we have the billing address, exact same thing as the shippingaddress. So we have address one, and we have address two. Then we have billing country,and we have Billings up. And instead of having two checkboxes here, too.One of them is thisbilling address is the same as my shipping address, we wouldn’t have that again. So allwe have here is set default billing. And then we’ll handle use default billing as well.So we can actually just copy this here. And right before the HR. And we can actually justget rid of that one there. Then instead of use default shipping, this would be used defaultbilling. And we can just do the same thing for over here.And add it in like that. Andthere we go. So now we have the billing address form, save as default billing address anduse default billing address. And now, we just want to make sure that these checkboxes areonly being displayed if we actually have a default billing address or default shippingaddress. So let’s go here into the view. And I’m going to get rid of all of that there.And let’s just go here into the get request. And we’ll actually need to import the addresswhich we do over there. And so here, we’re going to need to get some query sets. So runoff to the context, we can update the context, if we have a default shipping address. Sowhat we can do is, say, the shipping address, query set equals to the address, where wewill filter it based on the current user.And let’s just put this on a new line, thenwe will say that the address type is going to be billing or rather shipping in this case.And we’re going to say that default equals to true so that we get the default address.And then we can just say, if shipping address query set exists, then we will say contextdot update. And here we’ll say default shipping address is that shipping address, first item,and then we can copy this. And we’ll do the exact same thing for the billing address.So let’s just rename this billing address and change this to be, then if that queryset exists, we will set the default billing address is equal to billing address queryset of zero, cool, then we can come in here. And for this one for the billing address,we can just say if, and it’s just going to get that value there. So if default billingaddress is being passed into the context, then we will actually render this.And here,we can just get rid of that and actually output the default address. so here we can say, defaultbilling address, dot address. And then we can say, truncate characters to let’s say,10. And then we can copy that, and come back up here for the shipping address. And say,if us, or if there’s a default shipping address, then we will output it like that. And do theexact same thing over here. So if default shipping address, then we’ll say endif.Comeback. And let’s just see name request is not defined. So if we go back here, this is selfdot request dot user, and just add it in there. Okay. And refresh this. Cool. So now thosecheckboxes will only output if we actually have a default. And now we need to work onthe logic of what actually happens when we submit in the post request. So let’s justcome back down here. And we can actually close some of these files off. So the logic hereis first to check if we are using the default shipping address.So that means we’re goingto get the value from the cleaned data in the form. If that value is true, then we willuse the default address. If it’s false, then that means that we were expected to entersome information in the form. So let’s just come here and say use default shipping equalstwo. And we’ll just copy all of that there and grab that value from the clean data. Soif your connection is going to hear if that value is true, then I’m going to say printusing the default shipping address. And just like we did over here, I’m going to copy thatquery set and paste that all over here. And I’m just going to call it D Address queryset for short. So what we want to do is first check if this user actually has a defaultshipping address, because if they don’t, then we’re going to need to redirect back and displaysome sort of message.So we’ll just say, if it exists, then also the shipping addressequals to that address query, set the first value inside it. And then we can say else,messages, dot info. And we’ll pass self dot request and say, no default shipping addressavailable. And we can just go and copy one of these redirects here, back to the checkoutpage. So just like this, so we’re storing it in this shipping address variable, whichwe will either get from this condition, and then we can just go down and say else, thenwe can just say print user is entering a new shipping address. And we’ll do the exact samething where we assign this variable to be the address over here, which is going to bereceived or created in this exact same way that we have been doing previously.So I’mjust going to tab all of that inside. And we’ll just make sure we label everything appropriately.So let’s actually just go back into the form. And we’ll say that the shipping address equalsto that shipping address to equals to this. And then we have shipping country equals tothat value. And we have shipping sip equals to that, then the payment option, I’m justgoing to cut and paste over there, because we don’t need that for now.So this is theshipping address, which I’m going to rename, I’m going to change this to be shipping. Andthen we will pass in all of these values. And just make sure we save the shipping addressthing. And then we can say order dot shipping address equals to that. And what we’re goingto do is do it outside of the else statement. So that either way, we are storing it as theshipping address received from here, or as the new one over here. And I’ll actually justchange this label to be shipping address one, so we don’t get any kind of conflicts withvariable names. Cool. So now we are saving the shipping address onto the order. And atthis point, what we want to do is check if we are setting this current shipping addressthat we just created to be the new default. So what I’m going to do is say set defaultshipping equals to, and we will just copy all of that there and get the value from thatform and just say if set default shipping is true, then we just want to take that shippingaddress.And we’re just going to say dot default equals true. And then just say not safe. Sonow we’ve saved it as a default shipping address so that next time, we will be able to filterfor it and display that to the user. And basically all of this logic that we just did over here,for the shipping address, this is what we want to do. Well, everything from here, thisis what we want to do for the billing address as well. But inside here in the URL statement,if we are creating a new address, we’re going to want to validate these values over herebecause we’ve gone here in the form and specify that they are not required.And that couldlead to some issues where users could submit empty strings. And we obviously don’t wantthat. So we can just come up here above the class. And just to find a method that canhelp us with this. So I’ll just say this is, let’s say, is valid form. And we’ll just saythat it takes in a list of values. And we can say, for field in values, then we cancheck if that field is equal to an empty string. And above this for loop, we could have a totalvalue which is valid and say that it initially is valid. But the moment we get an empty string,we set it to be invalid. So we’ll just say if field equals an empty string, then we willsay valid equals to false.And then here to say return valid. And then here we can justtake that is valid form. And we’ll come here Right above the values here or just afterwe receive it, but below, and just above the shipping address where we created. So we’llsay, if is valid form. And here, we’ll just pass in a list of values. So the ones thatare required, which would be the shipping address, one, the shipping country and theshipping, zip. So if all of those values are valid, then we can just tab that in.So todo all of that logic, and otherwise, we can then just say, messages dot info of self dotrequest. And we’ll just say, Please fill in the required shipping address fields. Andthen we can just take all of that and put that inside the if statement as well. So justtablets in. And there we go, then what I’m going to do is basically copy all of this.And we can then can be lowered. And I’ll just paste it all there. And do the exact samething for us default billing. So we’ll say if use default billing is true, then we willsay using the default billing address, and we will filter for billing addresses. If theaddress exists, then we will create a billing address variable, which is the first itemin the query set, or say, no default billing address is available otherwise.And here we’llsay user is entering a new billing address. And we’ll just change the values inside here.And then we can just take all of these and make sure that we pass them into the new address.So I’ll just paste them all here. And make sure that this is a billing type address.And will you all label it as well. And pass in all of the values into the is valid formcheck, then we can say order dot billing address equals to that billing address and save it.And actually, we’ll need to save it on this condition as well. So let’s just add it overthere. And then we’ll do the same thing that we did for the shipping address over herein this condition as well.There we go. So now let’s just come back down. And we’ll dothe same thing here use default billing, or set default billing. So just added in there.So if that value is true, then we’ll say that the billing address default is equal to true.Also, please fill in the required billing address fields. And then there’s just onemore thing that we need to add, which is if we are using the same billing address as shippingaddress, so that’s going to be something that we need to check here at the beginning. Soover here, so we can just come and grab that value. So same billing address equals to andjust copy all of this. So what we should actually do first is check if that value is true.Sowe’ll say if same billing address, then what I’m going to do is set the billing addressequal to the shipping address, but I’m going to clone it. So I’m going to say that theprimary key equals none. And then we can say that save so that it creates a new address.And then we can say that the billing address dot address type equals to a billing address.And then we will say that save and then save it on to the order. So if this condition istrue, we will do all of that. Otherwise, we check if we’re using the default billing address.And otherwise, as the last condition, we’re assuming that the user is entering form data.So after this last l statement, we get the payment option and do the exact same thing,as usual.So if we check here, the server is still running. So we can come back hereand refresh this. And let’s just also go back and go to addresses. So we don’t have anyright now. So let’s enter some information. And I’m going to say Save as default. Thenwe can enter some other information in here. And I’m going to say Save as default as well.And we’ll say stripe, continue to checkout and if we come back in refresh this. Now wehave two default addresses. One is billing. One is shipping, caught. Now let’s go back.And I’m just refreshing this. And what I’m going to do is say, use default shipping address,and we’re not getting it displayed there. Let’s just see why that is. So street addressis actually the field we need to output. So let’s just come here and say this is streetaddress, then we can copy that and bring it to the billing address as well.So if we refreshthis, now we have that default street address showing as an indication. So if we selectboth of those, and then select stripe, and continue, that went through. So let’s alsogo back here to the order. And we’ll just come here and say that there is no relationshipto a shipping and billing address. And that’s your reference code is required. So what I’mgoing to do is go back here to the model, so we can change that. And this is on theorder. And here I’ll just add, blank and null or true for this field.And then we can justmake migrations, and then migrate, and then run the server. So let’s come back and refreshthis, click Continue. Okay, so now we don’t have a shipping or billing address, so wecan test this again. So let’s go back. And so we’re using default shipping using defaultbilling, click Continue. Go back, refresh this. And there we go. So now we have theshipping address and the billing address being used. And lastly, it’s let’s go and test anothercase. So just refresh there. And let’s go and delete those addresses as well. So justdelete those. And what we’re going to do is say, billing address is the same as my shippingaddress. So let’s just add information there. And select stripe, continue. OK, let’s comeback and refresh this.So now we have billing, and we have shipping, exact same information.And if we go back and go to the order, then it’s linking that same one as well. So thisseems to be working so far, what we can do now is just add in a little bit of jQueryto say that when we select the use default address, that it then toggles this display.So let’s go back here, and we can go into check out and just come all the way to thebottom. And let’s also open up based on HTML and just see here that we have these scriptsbeing included. So what are we going to do is add another block here, and we can justcall this the extra scripts. And then we can say, END block, extra scripts, then we cancopy that entire block there. And right here off the content, we’ll add in our new scriptover here. So let’s just open up a script tag. And if we just take a look here at theclasses we’ve added, so we have your high double shipping form, which I should actuallycall Hannibal billing form seeing as this is for the billing address.And then we havethe same thing here, which is high level shipping form. So I’m going to copy both of these two.And then here, we can just create some variables, then we’re just going to use jQuery and accessit with those classes. So just paste those values there. And then we’re also going toneed the checkboxes. So the first one being this one here, so having the name of use defaultshipping and an idea of use default shipping, and the other one is the shipping one or billingone.So here we’ll say variable. Use default shipping equals two, we can just say document,dot query selector. And we can just open up the input tag and say where the name is equalto use default shipping. And then this one will be use default billing and change thename in there. And all we need to do here is just say, if use default shipping is changed,which we can handle With an event listener, so we can just say add event listener, andlisten for the change event, then we can create a function as a callback.And we’ll just sayif this dot checked, which is a property on the checkbox, HTML tag. So if it is checked,then we’re going to say hi, double shipping form dot hide, which is that jQuery method.And then we can say, otherwise, high level shipping form dot show. And we can call thesemethods because we’re accessing these variables with the jQuery selector. So I can just copythis entire script tag there.And we’ll say that this is for the use default billing,and then say, Hi, double billing form, dot hide or show. Now if we come back and refreshthis, we’ll just go back into the admin and let’s just go to those addresses. And thenwe can just say that they were default. And this one is also default, refresh this. Soif I select use default, you can see a toggle that form.And that way, we at least, getthis indication that we don’t need to fill in any of the other form fields, if we doselect this. And this is then a lot better than just leaving it open. So at least providingsome information to the user. Click Continue. And it takes you to this page where we’veseen the payment process does work. So that’s all we wanted to handle in this one, whichwas just improving this checkout process of adding a billing address and a shipping address.So now we can at least control that information much better and stored more accurately.Andalso provide a better way of our users actually entering that information by providing thisdefault option. And also, the concept of billing address is the same as my shipping address,then we could actually do the exact same thing for that toggle. So if you toggle this one,it could either pre populate this form or cause a drop down where it hides or showsit. But now that you’ve seen how we can do it with this toggle example, you can try andimplement this one yourself. So we’re just going to leave it at this. Now before gettingstarted, I just want to point out that we are not going to be teaching how to storecredit card information ourselves that’s not secure. And it’s not a good way to do it,we’re either going to be using stripe to store that information as they are the payment processor.And that’s what they’re built to do.So this tutorial is going to focus on retrieving thatinformation from stripe and not storing it ourselves. Okay, so in this one, we’re goingto be adding functionality that allows a user to similar to the last video where you coulduse a default billing address. Now we’re allowing you to have a default payment method, particularlywith stripe, so basically a default card that you can use in the rest of your purchases.So you don’t have to keep on adding that card number every time you want to make a payment,you can just select that card.And we’ve already gone and implemented this functionality. Sothe format of this video is going to be a little bit different in that we’re not goingto be building it in this video rather just walking through the functionality that hasbeen added already. And this is just because it’s not actually a lot of code. And it’snot a lot of functionality. The concept is pretty much the exact same as in the previousvideo where we were just allowing a user to click a checkbox, which would then basicallyshow the user what they’re allowed to see in the form, which would either be enteringa new billing address or selecting the current one that they have the exact same conceptas that.So if you haven’t watched the previous video, then I suggest rather go ahead andwatch that video as that video contains basically the logic that was used to fill in this functionalityin this video. But basically, the concept is that if I add something to cart, and justproceed to checkout, then let’s just use a default billing address and default shippingaddress select stripe. And the idea is basically that we have this checkbox here that I canselect and it says use default card. And then we have the first 12 digits that are juststars because you don’t know what they are.And then it gives you an indication of whatthat card is. So the last four digits and then the expiration date. And basically likethis, you can either select to use this default card and pay with this because this is linkedto your profile. Or you can go and add a new card over here as usual. And you can eithersave this for future purposes or not. So it’s the exact same concept as the previous videoand let’s just go and walk through the code that was added to do this. So We’ll startoff in our models.And basically, for us to show the user any card that they have usedbefore in a purchase. That would mean that we have to store some of that informationsomehow. So what we’ve done is added a user profile model, which is basically linked toa user with a one to one field. So every user has their own user profile. And we use thepost save signal to create that user profile, the moment that the user is created. So wejust specify the sender as that auth user model. And we say if that instance, so theuser, if the user is created, then we just call user profile on objects dot create andjust pass in the user as the only required argument, which basically creates that usersuser profile.And by default, you’re not going to have a stripe customer ID and you’re notgoing to have one click purchasing activated. This one click purchasing is more of a conceptthan actual functionality right now. So that’s something that we could add in future videos.But basically, you have these two fields as kind of like settings on the user. And theycan then go and configure this later on. So the stripe customer ID will get populatedif they decide to save their customer information when they check out. And that being, if theywere to say save for future purchases, and enter their card information here, then weneed to store that information.So what we do is here in the view, we’ll just go allthe way to the top of this payment view. So let’s just look at the POST method first.Basically, what’s happening is, we’re now receiving the token and some extra informationfrom the form, which is firstly, the Save value, which is basically whether or not weshould save the current card that the user just inputted into the form. And then usedefault means use the default card. So that’s the only information we’re getting from ourpost request. If we are saving it, then all we do is assign it to the user.So we firstcheck if there is a stripe customer ID associated on that user profile. If there isn’t one,then that means that this is the first time they’re saving information. So what we dois we create the stripe customer. And we pass in the source as the card that they just putin and just create that user profile, where we’re assigning the stripe customer ID asthe ID of this API call over here. And then we can also just set one click purchasingequal to true for future references, save the user profile. And otherwise, if the userprofile does exist already, then all we’re doing is creating a source.So you can callstripe dot customer dot create source, which only takes in the customer ID and the source.So that will basically add a new source onto the customer. And that’s all the functionalityis for whether or not we want to save information, then we go on to actually processing the charge.So if we’re using the default card on the user’s profile, then we simply just have topass in the customer into the stripe dot charge create API call. Whereas if we’re not usingthe default card, then we have to pass in the source that we want to charge. And basically,you could view this as one is for users that have kind of like a profile, and one is forusers that are making sort of like an anonymous purchase. So for one, you’re basically allowingus to retrieve your past credit card information, and the other you’re not.So you have to enterthat every single time. And that’s the only change that’s been made. In charging the user,basically just one of these two methods has to occur. And everything after that is exactlythe same. We create the payment and perform the rest of the billing logic here. But thisis just for the POST method. If we take a look here at the get method. Here, what we’redoing is we’re grabbing the user profile, and we’re checking if one click purchasingis activated.And if it is, then what we do is we fetch the users cards, which is listedon their stripe customer. So what we do is just called stripe customer dot list sources.And then here you just pass in the arguments, which are the stripe customer ID, the limitof how many results you want to get back, which is set to three and then the type ofobject that you want to filter for, because you get many different sources that stripeactually handles. So we’re only looking for cards as the specific object. So we just passan object as card. And now we’ll have a list of cards, which we can either iterate throughor we can just grab the first one, which is what we’re doing here. So we’re checking ifthe list of that card is greater than zero, then we just update the context to have acard. And then that card we output here in our HTML by just using some template syntaxhere.So we just say if there’s a card, we are put just another div which has a checkboxin it. And inside of here you can see we are putting, for example the last four which arethe last four digits On the card, the expiration month, the expiration year. So we are putall of that if there is a card. And then we’ve just restructured the template similar toin the last video, we now we just added some JavaScript down here that based on the input,that is a checkbox, if you do select it, then it will hide the one form and show the otherform, and vice versa. So basically, what we can do is we can log out, and we will signup with a new user. Okay, cool, we can now go and add something to the cart, proceedto checkout. And let’s just enter some information, select stripe continue to check out. Therewe go. Now we can see that we aren’t getting that checkbox because we don’t have any cardsat the moment.And let’s go and open up an incognito window just so we can go into theadmin. We can go to user profiles, go to that new user. And there we go. So no stripe customerID, and one click purchasing not active yet. Now let’s just go back here. And what I’lldo is input some credit card information, click Save for future purchases, and clickSubmit. Cool. And so now the order was successful. And if we check the admin, the customer IDis now there, one click purchasing is now there. So if we try and add something again,and let’s just go use default, and select stripe continue to check out. And now we havethe option to use a default card so we can select that submit the payment and order wassuccessful.And so that’s all we wanted to show in this video, which was basically justtaking the same logic from the previous video of how you can save a default address in thesame way by storing a default payment method, which in this case is in the form of a creditcard. And the best thing about it is that we aren’t actually storing that informationourselves. We’re always fetching that from stripe, which makes it much better. So ifyou enjoyed this video, then leave a comment down below. Let us know what you thought.Otherwise, thanks for watching. Don’t forget to subscribe and we’ll see you in the nextone..

As found on YouTube

Share this article

Leave a comment