Todo App | Django REST Framework & Ajax

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
okay so in this video we're gonna build a to-do app using Django and a back-end that we set up with the Django rest framework so I've made a video like this before but now what we're actually going to do is work with an API that we set up and use JavaScript on the front end to make those API calls and actually handle that crud functionality so if you take a look at our app here we're able to update items just by clicking on them crossing them off the list and if I want to update something I could just go ahead and do something like this and say update and also add a new item so this is all done asynchronously so if you look at our console here every move I made rendered out a new set of data for us so what's happening here is JavaScript is making an API call to the backend and everything we do it returns more data for us and rear Enders out this page so we're gonna work off of this REST API that we built out using the Django rest framework and this is where we are pulling data from so if you want to follow along with this video in the first part I actually set up this back end so I'll recommend you follow along with that get all of this set up and then in this video all we're gonna do is make API calls to that and handle this on the front end so I am gonna upload the source code to the start of this project and the final version so you could just work with that if you already understand the Django rest framework but I would highly recommend you see what we did in the first video which I will link up and follow along with that okay so before we get started with the to do app let's go ahead and recap what we set up in the last video so this is our API that we built out and if you take a look here these are the URL patterns that we can visit so this is just to get the data in a list to view an individual item create an item update an item and to delete an item so we have those URL patterns and here are the views that go with those so again these are all API views because of this decorator and they all take in a different method so this one takes in delete post get requests for the detail and the list and we have our serializer and our model of tasks so that kind of summarizes the entire project right there and we also do have an app that we called API and that's just the way we set this one up but now what we're gonna do is create a new app and we will just call this one front-end so this new app will just pull the data from this API and we'll just reference these URLs so let's go ahead and do that and we're just gonna call the new app front and so python managed dot py start app and we'll just say front end and that should give us our new app so let's go ahead and configure that so here we go front end and we need to go into settings down py and make sure we have that so our project is to do underscore DRF and in here I'm just gonna copy this and add in the new app so we have two apps API and front-end and front-end is gonna pull in from that so let's go ahead and change this front-end and this will be to front and config front and config and that should do it so let's go ahead and run our server and we're gonna configure our URLs right now so python managed to py run server and let's take a look and see what we have so far so right now if we go to our project all of our UL URLs here so if we go to the base URL we get nothing because we didn't configure that but if we go to API we're able to go to these paths and actually access everything and that is because if we go to our main project file we don't have a relative path to that to that template so that's what we're gonna set up now so now let's go ahead and set that up we'll just create a path and this will be that base URL and we'll just include front end dot URL so front end dot URLs and we'll create that file and render template now so let's go ahead and set that up so in front-end let's create that folder and let's say templates and within templates we need a file called front-end so the name of our app and we will just call this one index.html actually let's just go ahead and call that list dot HTML because it's a little bit more appropriate for what we have here so let's just make sure we you can see that when we render it and we'll just say hello and now for our URLs in order to set that up we need to create that file and I know this is a lot of basic stuff but I just want to make sure that I don't copy and paste too much code or confuse anyone here so I do want to start from the beginning so URLs up UI I'm just gonna go ahead and copy everything from that the API URL and we will reset these and go ahead and just render out the list which is gonna be the view that we're gonna create so list and we'll just call this one list so I'm kind of doing things backwards here but now in our views in the front-end app within views let's go ahead and create that so we'll just say new function list request and we will just return that template so return render and we're just gonna do front and four slash list dot HTML so that should set it up I don't think I mix anything up here let's go ahead and close out a bunch of these tabs because we are starting to open up too much here so there's a model or URLs and let's give this a test so now if we go to that URL my server is on let's try to restart that ok so now if we go to that home page we should see our dashboard up here ok so there we go we have our template so now what I'm gonna do is actually set up that HTML and CSS for this I will copy and paste but I'll go line while just to get this set up and we'll start making API calls so let's go ahead and in our template here so in list dot HTML I'm gonna start setting things up so let's go ahead and create our HTML tag and we'll set that up we'll just say to do and the first thing we'll import is going to be bootstrap and some fonts so within the head tag make some space here will paste in bootstrap so you can grab that from the bootstrap CDN and or just use my source code and here is the fonts we're gonna work with again not too relevant to the app but I do want to make sure there is styling so for the rest of the styling I am actually gonna handle this in line so I don't want to have to connect static files or anything like that for a tutorial like this so we'll go ahead and just do everything in here so the first thing we'll do is set up our background color and this is gonna be what you saw in that demo which is a gradient blue and green background so if you want to take a look at this will actually need to add something to our template so we can actually see it so you rewrite hello there and let's see what that gives us so for the template that's just going to give us this background so now what we want to do is apply that font that we just imported and we want to apply it to all the text we're going to use so we're going to apply that to h1 through strike tag and we're just going to apply this Google font that we wanted in here now what else or the next thing we want to do is apply that container styling so task container is just going to be the wrapper that's going to contain all of the elements in here so if I want to set up that HTML I'll actually copy that in right now and we'll style it so not in the styling but within the body here so here we're using a bootstrap container the container here will hold all the elements so it ends right here it's ER it wraps everything up here and the we have our form wrapper that ends right here and our list wrapper that will contain the items so if i refresh this you should see actually if we have a list here so that's that wrapper that we just styled so let's go ahead and finish up the styling with a few more things here so the next thing we want to do is add some styling to the form wrapper which will give us some padding here and make that look a little better so if we want to see that let's go ahead and refresh that there we go so it gives us that styling and we also want to style that submit button so we'll put that in that'll make that button green and we change the ID of that button to submit and we're also using the Flex grid here to make sure that's in line and I'll just paste in two more classes which is going to be that flex wrapper and task wrapper so this will be the actual list so flex wrapper is referenced right here around that input field and the button so didn't want to spend too much time on this section but there we go so now once we start outputting data our list will appear down here and it's going to look good so if we go to our CSS we didn't add too much we just add a little HTML and some styling so let's go ahead and start writing some JavaScript here and I'll just go ahead and include that I believe I should put that into you or inside the body tag yeah so we'll just put that in here and we'll just say script and this is where we're gonna start rendering our data so let's go ahead and make an API call and render out some stuff from our back-end so I'll just add in some comments here and this is something that I'll reference later but I like to do this when I'm building apps here so I can understand the data flow and the structure so I'll throw that in and cover each piece line by line as we go and the first function we're gonna build is going to be called build list and this function is going to be responsible for calling data and outputting it to our wrapper there so we want to first select our rapper to where that where those items will be output to so we want to get the ID of list rapper so we'll just do rapper is going to equal to document dot get element by ID and that will just be list - rapper and now we need to call the data so I'm gonna use a fetch API for this so we'll just set that URL so the URL we're gonna call to at this at the beginning at least is gonna be this data right here so if we go back here we want to call this URL and retrieve this in an array of JSON objects so we'll throw that in and let's go ahead and do fetch so fetch and we'll just do dot then and actually we need to pass in a URL so we'll throw that in and then and we need to get that data and turn it into a JSON response so we'll just do our SP and that will be an arrow function and we're just gonna do our SP so the response dot JSON and we're gonna convert that and once we have that data we're gonna do doc then again and we need to actually console this data out I just want to make sure we made that call properly so function and this time we're gonna use a normal function and we'll just go ahead and console don't log and we need a passing data right here so I can actually reference it and let's go ahead and just do data and console that out so again if you're following this I recommend you either just follow the step by step definitely read into the fetch API if you haven't used it I've used jQuery in the past but I'm trying to get away from that and use something more native to JavaScript so if we go to our app now and inspect we should see this data console doubt here if that ran properly we actually need to call the function I just realized so let's go ahead and once we make the function up here we can actually just call it so build list and gonna call the function onload so there we go so we now have our data and we made a successful API call to the database so let's go ahead and actually render this so we'll loop through the list here and we're just going to go ahead and output the data and append it to this wrapper right here so what I'm gonna do is set the value of data to this variable list and that's gonna be equal to data and we're just we're just going to create a for loop and we'll just say for VAR i in list and let's go ahead and create an element on each iteration so what i'm gonna do is create a div that will contain the title and some buttons and then we'll append it so we're going to say VAR item and again this is created on each iteration and we're gonna use template literals here and i'm gonna create a div and this is going to be the wrapper to each item to the actual data itself so we're gonna create the div and within here i'm gonna call this div and I'm actually gonna copy and paste some stuff here and I'll explain what's going on so I'll paste that in here so we're gonna give it we're gonna give each item its own ID so the ID is gonna be data - row and whatever iteration we're currently on based on that and we're also gonna have the class name of task wrapper which will give it this styling which we'll see in a second and we're also gonna give it flex wrapper so we're able to style those items in line so now what we want to do is throw in some span tags and in here first we're gonna set up the Flex wrapper so we're just gonna do div and we're gonna wrap each item within this within this row with this flex wrapper so we're gonna style it in line so I'll just do style is going to be equal to make sure to actually put the Eldar so this one will be flex and we want this to be the bigger item in that row so we'll just do that and there we'll throw in the span tag and we'll access the list item title there so if you look at that response we're grabbing each items title right here so that's how we're able to access it in a JSON response so what I'll do is actually copy and paste this three times so this one's gonna be flexed one because these are buttons so we want them aligned to the right and in here what we're gonna do is just throw in a button so I'm gonna say edit button for this one so we're gonna create a button give it the class of BTN the bootstrap class BTN small and we're gonna outline it and give it the class of edit which will reference later and for this one this is going to be a button it's just gonna have a dash and when we click on it we just want to delete it and we're gonna give it the bootstrap styling of outline and dark so once we create the item what we want to do now is append each item to that list wrapper so we give it the ID of wrapper here so we query that list wrapper and within the loop we want to make sure that it's in here because we're creating each element we want to do wrapper dot inner HTML and we'll just do plus equals and that's where we are throwing in the item here so let's go ahead and save that refresh it and make sure it's working so there we go that's all the styling we applied I'll recommend just looking into that and seeing how I output that but right now we're outputting the data nothing is actually working we can't really do anything with it but we've rendered out the data and we've made a successful API call so starting to come together so now what we need to do is actually give ourselves the ability to create items on that form submission so let's go ahead and do that so outside of this function this build list function what I'm gonna do is create an event listener and on our form we give it the ID of form - wrapper so I'll copy that and we'll just go ahead and create a variable called form so far our form and that's going to be equal to document dot get element by ID and we'll just throw in that form wrapper so we have the form we're just gonna say form dot addeventlistener and the eventlistener we want to listen for is going to be submit or the events we want to listen to a submit and we'll just go ahead and add the function and the first thing we want to do is prevent the form from submitting on its own so we want to take care of everything with JavaScript so we're gonna do prevent default and that's gonna stop our form from submitting and let's just go ahead and console it out and make sure it's working so just console out to form submitted but it won't send any data so form submitted and let's go ahead and give it a try make sure the event handler is added and did something around here let's see what's going on document don't get element by ID oh I forgot to put equals here so form equals document dot get element by ID and now that should work okay so when we submit our form we're gonna see this alert but nothing's gonna happen so let's go ahead and actually submit some data and we're actually gonna run into an error because of because of the way we're sending our CSRF token because in Django we normally add this into the form but we're using javascript to submit this so I'll run into the air and then show you how to fix it so to submit the post data we're also going to use the fetch API and I am actually gonna grab this URL and just update it so we're gonna throw that in here and this is going to be task - create and that's just the way we set up our API if we go to the URL patterns if we go to API and URL so task create will create the task for us so let's go ahead and set up that fetch call and we'll just do fetch and in here what we're gonna do is throw in the URL and now we actually need to throw in some parameters so we're gonna create a dictionary here and we're gonna say method and that's going to equal to post and we're also going to pass in some headers so headers is going to be another dictionary and we're just gonna say content type and I need make that capital C right there so content - type and this is gonna be application forward slash JSON so application for slash JSON there and we're not gonna pass him that CRS our up token yet but it is gonna go underneath here so once we have that we're also gonna throw in the body so what data do we want to send and the body is gonna be that data string applied so I'll just do json stringify and i'll explain what's going on here in a second so we're gonna stringify any data that we throw in here so what we're gonna do now is actually throw in an object and i'm just gonna call it title or so the attributes gonna be titled because that's what we're trying to send to the backend and the title we're gonna get I'll throw in the variable here but we'll grab it right here and we'll just say title is gonna be equal to document dot get element by ID so I'll just go ahead and grab this and sort of having to type that out and this this element is going to be that form field so we're gonna get this element right here so the ID is title so we're gonna grab whatever is in here so we're gonna do a document dot get element by ID and where is that okay so that's the title so we're gonna do title dot value so the ID name is title and we just want to get the value of it so we're gonna grab that value and we're gonna throw it into this object and again because we're using the fetch API we're gonna stringify it and then we're gonna send it to the backend so once that's done once we send the data what we want to do now is actually call that build list again so we want to submit data and we want to rerender that list so there's different ways you can do this i just rear-ended the list each time so we'll do it up then and in here we're just gonna do function and we're gonna get the response and we'll just say build list so we'll call that function again and we'll just go ahead and add a comma there we need to make sure to close that off there and if i refresh this we should see an air and we are gonna get a bunch of rows output here because we need to refresh this so let me show you what I mean I will just say latest item and if I submit this we should get back a response that gives us an error and I'm not exactly sure how this works with the Django rest framework but I do still think we need to send that CSRF token I'm still doing a little research on it but I'll just go ahead and add that and fix this error for now so what's happening here is the data was submitted and it didn't run because we didn't send a CSRF token with it so it gave us an error but we did run that run build function again so we have the same data twice so new item update new item update so it's just repeating it so what we need to do is actually go ahead and in our build list function we are gonna clear out the wrapper on each new render so any rows in there before we re render new rows we're gonna go ahead and clear it out so we're going to say inner dot HTML and that's gonna equal to just a string value which will just set our wrapper to just an empty div and then we'll go back through that process and render out each row so now I'm gonna drag in the Django documentation for that CSRF token and if you I'll actually link this up but if you look up how to send that CSRF token with Ajax Django actually gives us a way to create one and send it with our post data if we're submitting submitting it with Ajax so I'll copy that and in or at the top of our script here so just under our notes I'm gonna go ahead and paste that in and we'll fix this up and I'll explain what's going on here we don't need to know the details of what's going on here but basically Django is creating a token for us and throws it into this variable so now in our post data we can actually add it to our headers here so in our headers we can add it as we'll do a string value here and we'll just say X - CSRF token and then we'll just do : and we'll grab this token right here so just make sure that's in here you can store it any way you want as long as you can reference it I put this in a different javascript file and just rendered it but we can grab that and now when we submit the data the token will be sent with that post data and then our our list will be cleared and we'll see new data rendered out in a completely different way so it won't build up on top of it so let's go ahead and try this so we'll just say latest item and I'll hit submit and there we go so that item was just added and one thing I want to do is invert it so the latest item is at the top so I'll go back to my view and in my views that py file in here we'll just say order by and normally you want to do this by date or something like that but I'm just gonna do it by ID because my IDs are integers so we'll just say ID and now when we refresh it you'll notice that list item should be on the top now so there we go so there's a few things I want to do here when we create a form we also want to clear that form field so right now if we submit it the form will still stay with the element that was currently in it so on submit after we build let's go ahead and do document let's go ahead and actually grab this right here and we'll just say document dot get element by ID and the name of our form is just form so that just to make sure that that's all correct up here our form is called form so we're just gonna do form dot reset so this will just clear our form data so we'll do form dot reset and let's go ahead and see what this does so now if I add an item I'll just do one it's at the top and what's going on here reset isn't a function looks like I've misspelled that reset okay so now when I add these items so it's still added it but if I just go ahead and - there we go so our form is now cleared and the items are being added so there's something else I want to show you here with that form so I'll go ahead and add a few more items here so if I just do this and you'll notice that every time i refresh it we see this kind of this flash and that's because the page is rerender this gets rebuilt each time so I also added this effect here where it stays it pretty much gets fixed to the top of this inner wrapper so if you want to see that that's in this CSS right here I won't go into detail but this allows us to set that up but why that can be a problem is let's say we want to update this item here well if we're scrolled down and let's say we click it we want to edit it we just make some kind of edit we'll just say I'm just adding some data there we automatically get sent back to the top because what happens is this table or this wrapper gets shrunk and then rebuilt so we'll fix that later but for now I just wanted to show you that air and show you how to clear the form so let's go ahead and get into updating items so we'll actually give ourselves the ability to click on that edit button and start editing an item okay so for this next part I'm going to go as slow as possible because I do need to explain what's going on here because editing could get a little tricky in the way that I'm doing it and this is the best way I can figure out how to make this happen so just to recap the way that that submission process worked was that we grabbed the form data and we sent it to the back end and this dictionary stringify it just gets sent back to our view so in this view we take in that data right there we throw it into the serializer and we say if steriliser is valid just like we would a form we save it and we return a response so there's a few things that we need to do with the Edit item so first we're gonna create a function that is going to be called edit item and it's going to trigger whenever we click on one of these buttons here so anytime we click one of these we're gonna just console out edit button was clicked and we want to specify which item was clicked so let's go ahead and do that and just under this form submission this event listener we're gonna create a function called edit items so edit item and for now we're just gonna console out item click so console dot log and we're just gonna say item clicked ok so this is where I realize any JavaScript a little less than I thought I did so I thought that in our loop here so as we build each item we can just go ahead and select this class in the curve iteration and add an event handler so let's go ahead and try that and I'll show you what happens so I'll try to run this step-by-step so we're gonna create a new variable called edit BTN and this was just gonna be document dot get elements because we're doing class so get elements by class name and we're gonna get the edit class and we want to get the current iteration so in this case we're looping with the variable of I so we're just gonna get the current button here so once we do that the logic that I had was that we can just go ahead and add an event listener so add event listener and we were just gonna go ahead and trigger it on click thrown Ellender and on click we're just gonna do function and we were just gonna trigger this Edit item event so let's go ahead and see what happens once we do this so right here will trigger it and let's give that a test so if i refresh that and click it nothing happens nothing happens and if I click on the last item there we go the function triggers so what's happening here is because we're doing this through that loop it's actually somehow it's actually not storing that value and adding it only to the last iteration so that event only gets out of here I won't go into detail and why that's happening but I had to read a bunch of articles to understand what was going on but definitely don't know enough to actually explain it so again the event only gets added to the last item so the solution was to go ahead and grab all of this so let's grab this loop right here and at the end of the loop so it ends right here we're gonna loop through one more time so once it gets built we're just gonna create one more loop and do this in here so this solves the temporary problem so now if I do this and go ahead and refresh that we should get that event triggered on each item click so the next problem occurred when I wanted to add in an object so I wanted to be able to pass in the current item so let's just say list I I wanted to be able to throw that in here and then be able to actually work with it so let's say we want to click on that item and we want to see which item was which item were working with because we want to be able to manipulate it and fill in this form so if I do that what's happening here is the item is working with each with each button but the object itself is actually only this last object so if you look in the console no matter what item I click on so if I click on 2 we're always going to get this last item configure URLs and basic response so it doesn't change so the only object that gets passed in is the last one so it was kind of like that first object or that first issue that we ran into when the event was only passed into the last one so the solution is immediately invoked function expressions and I won't go into explain trying to explain what that is but I'll just show you the solution so I'd highly recommend looking those up and seeing how we can actually make this work so at the end of our event what we're going to do is change up how we return our function so what we're gonna do now is on click we have our function and we are gonna pass in the parameter so I call my parameter we'll just do item so we'll follow this we'll throw an item right here and we're gonna just remove this for now so I have it copied and we're gonna return a new function in here so basically this is going to allow us to store the variable in that function so I'm probably butchering how I'm explaining this but essentially we have our function we have our parameter we return another function and then we return item and where we're gonna pass in the actual task is going to be at the end so at the end here we're gonna do another set of parentheses and just to clear this up we have our event listener that ends right here and right here we're just going to pass in our not the function itself but this list item so list I and that's gonna be the actual object so this is going to let us store that reference in that local state for that function so once we set that up and we go down here we're constantly in the item I probably completely butcher the explanation but I'll show you what that does so let's see what's going on here the event listener is not a function I actually think we need to be inside of the event listener give me a second to fix this so we actually need to wrap this function and add one more set of parentheses there so it kind of looks funny and now if I save that and go ahead and see this make sure it looks right okay so now when I click on two we should see two and when I click on last item we should see last items so the object is being passed in and there's a reason why I'm trying to do this so in my script here we're gonna set a variable called active item and it's gonna have it's going to be a global variable so var active item is always going to be set to null so by default active item is null and the point of this is to know whether we are editing an item or creating a new one so whenever edit item gets clicked it does two things it sets active item to the object that we clicked on so that's why we needed to store that reference and we also need to set the value of form two to this item so let's go ahead and do this document dot get element by ID and we're only doing one value here so we're just going to set title and we're just gonna do dot value is gonna be equal to active item dot title so because active item is going to be set to whatever object we clicked on so it's going to be one of these it has a dot title so now we're just gonna do active item dot title here and it's just gonna set it right now so let's go ahead and test this out first before we handle submission so now when we click on an item each item I click on will appear here so active item is set and the form is now pre-populated with that item so the last thing we need to do with active item is handle submission so we need to make sure that the form knows whether to send it to a new item or one that we already have so we just need to change up the URL and title will always stay the same so what we're gonna do is by default the URL is set to create and we need to ask a question so we're gonna say if and we're gonna use active item so if active item is not equal to null let's go ahead and change the URL so it means we want to edit an item so I'll just grab this URL and in here we'll just go ahead and change this to task update and we are gonna pass in that active item which is why we want to store a globally so we want to pass in the active item ID so I'm gonna change these two template literals and let's go ahead and fix that okay so active item dot ID so now we're actually sending it to a specific items URL so the URL is changed and after we submit it we want to change active item back to null so we've preset the URL and we go ahead and reset that so now if I go ahead and pick an item so for and just go ahead and do update it so for is now updated so what happened is because the item was active we sent it to this URL which pulls up this view here so item update or task update we query the task based off of the ID we set the instance passing the new data and the item gets updated so that's what that does for us next we'll handle actually striking out data deleting it and it will fix that render so let's go ahead and create that delete method so under edit item we're gonna create a new function and this one's going to be called delete item function and we'll just do delete item and we'll pass in the item so we're also gonna throw on the object and we actually want to reference the ID so that's why we need to do this and delete item what we're gonna do now for this let's just go ahead and console it out and say delete clicked just to make sure it's all working so delete clicked and up here we're actually gonna use that same loop and grab the delete button so if you look here we also added the same ID like we did to edit but we added ID as a class name so alright we add a delete as a class name not ID so in here what we're gonna do is go ahead and create an edit button variable or a delete button variable and this will just be delete and we'll grab that class so again we're just querying that one instance of it and in here we're actually gonna copy the same exact method so we're gonna go ahead and move this down create some space here and this is where we're gonna handle delete so delete is gonna be added as an event handler here on click go ahead and run delete item so let's test this and make sure the object is passed in so if i refresh that there we go delete clicked and I actually already know the object is being passed in because we're using the same method so I just forgot to cancel that but we know it's working so for delete anytime we click it we want to in this function just go ahead and use the fetch method here and send delete request to our database so if you look at our view it takes in delete instead of post so let's go ahead and set that up so our URL is gonna be we'll actually just copy one of these here so let's actually grab this entire thing because we're just grabbing the item we're just gonna set the URL to that and we need to get the item ID not the active item ID so after this what we need to do is go ahead and send some more data so we add a comma and we're gonna go ahead and set method to delete so if you look at our view we only accept it we only accept the delete method so we'll throw that in delete and in our headers we're just gonna go ahead and add what we had before so headers colon and in this dictionary let's go ahead and just grab what we used earlier so a CSRF token and the content type so we're gonna pass in that data we're gonna send in that items ID so now we just have to go ahead and rebuild that list so we'll go ahead and throw in the response and here we're just gonna do an arrow function and run build so let's go ahead and grab build list paste that in so this should now delete an item for us by sending it to this to this view and go ahead and just rebuild up for us so if i refresh this and we do delete delete' there we go so now we're deleting items let's go ahead and add the ability to click on these and either strike them out as complete or maybe undo that so let's go ahead and create a function called strike on strike and we'll just do strike on strike so you will be capitalized and we'll go ahead and pass in the item again and not items by item and we're just gonna test this again by constant let out and making sure that the event handler works so console.log and we'll just say strike clicked and now we can grab this function and bring it up here so edit delete and we're actually just going to repeat this too so at the end of this event listener will just add it here so delete button and remove that from their pass and that strike on strike function list item and we need to get this strike button here so we'll just copy this and we'll call this one title because that's what it is and I think I called it title in class yeah so I just want to stay consistent with that on theory I probably should name that your strike but in here we're just gonna say title on click go ahead and run strike on strike so if I test this let's go ahead and refresh it now on click we should see that event handler working so it's all working let's actually process the functionality so the functionality will actually be a lot like the delete method we're down here I'll actually copy most of this right here and we want to also rebuild a list of everything from fetch to the end of that then responds there so we have that and we'll say task and what did I call this one where am i sending it let's go ahead and take a look so in my view we want to update it so we're just going to go ahead and send it to the update method but we're just sending different data so update and we're gonna send this as post and for the body what we want to do is pass in the complete status and I'll just go ahead and throw in the title I'm not sure if we can submit it without that I don't remember if I required it but we're just gonna go ahead and send it so we'll just say title and title is going to be equal to whichever item we have dot title so we'll just pass that back in and the completed attribute so if we go to our model and look at this we have our completed attribute so we'll set completed to the value of item dot completed so item dot completed and we need to make sure that every time we click this we get the opposite of what the last value was so right here what I'm going to say is item dot completed is going to be equal to the item dot completed but inverted so if item dot completed is true this time it's going to be false and if we click on it again if it's false now it's going to be true so it'll invert every single time we're just gonna send that back to that update view and we should get our list rebuilt so let's go ahead and test that so if I click on it and it looks like we have a bad request let's see what's going on here oh I think it's because I didn't stringify the data so let's go ahead and do json stringify and we'll just go ahead and close that and close that off right here so now if I do that that should update the data so let's go ahead and try that so latest item there we go so if I look right here completed is now true so what I want to do now is make sure that each time we render this out we have something that checks whether that item is completed or not and it renders it out as crossed out or just as a span tag so let's go ahead and update that so for that we're going to go up to r2 this item right here wherever we render it and what I want to do is check the condition and change the value of this so up here what I'm gonna do is create a new item and we're gonna set this to bar title and title is just gonna be just this span tag here so let's go ahead and grab this and throw it in here so let's use template literals throw that in there and in here what I'm gonna do is change this to that dynamic value so we're gonna grab this title and we'll throw it in here so what I need to do now is check a conditional and change the value if our item is completed so we're gonna say if and go and close that out so if the current iteration if the item and the current iteration right now is completed oops that's a square brackets there so not completed so if completed is equal to true let's go ahead and set the value of title so we'll grab this and we'll change the value to strike so instead of spam we'll say strike and strike we'll just cross it out for us so we'll return the same exact thing except we're now crossed out and this value gets thrown in there so let's go ahead and refresh that and give it a test so if i refresh it we click on this item it's now striked out and reloads every time so this successfully changes the value of the item and actually crosses it out so the last thing I want to fix is this little effect right here so you notice every time we click you're seeing this I keep calling it a flash method but basically it looks like a little glitch here that's the page re rendering so on the first iteration of the loop we clear out this wrapper I'm sure you remember that so we clear out the wrapper and we re render that data so one problem that can occur here is and I think I mentioned this earlier but whenever we're trying to update an item down the list so let's say that we want to update this so let's go ahead and just say update and we save that we want to keep our current placement and actually be able to see that update take effect so this is kind of a little bonus we're done with all the crud functionality this is more of just a front-end thing so I found one solution here and I'm not sure if this is the best method but basically what we're doing here is we're adding an item or we're adding an ID to each row and instead of clearing out the entire the entire wrapper here before we delete it what we're gonna do is actually before we add a new item we're gonna query the item with that ID that was previously there and we're gonna remove it so basically if you imagine it looping this way right here so this item would get removed and the new one we get would get added this one would get removed new one or two get added and so on so I don't know if that makes sense but let's go ahead and try this I'll just go ahead and keep accidentally closing out the text editor here so in here we're gonna are with the original loop so within our wrapper we're gonna comment this out so if you want to keep that I'll just leave it there just so you can reference it and what we're gonna do is grab each element by ID so let's create some space and we're gonna say document dot get element by ID so on each iteration what we want to do is if you look at this we have an ID for each item so we're gonna get data row and we're gonna use template literals for this because we need to pass in the ID based on the iteration we're gonna grab that element and we're gonna remove it so one problem that will occur with this is if that element doesn't exist it's gonna give us an error so what we're gonna use is just a try/catch and again if you really know how to do this I'm probably very inexperienced this is something that I kind of just face the issue and found a way to solve it I don't know if this is the best method so we'll just say try catch and if we do get an error just go ahead and ignore it I believe I have to put in something here and before I make a stupid mistake here this needs to be in our loop not in the beginning of build list so we commented that out and that's what threw me off so in the beginning of this loop we'll throw that in here and I'll just fix that indentation so basically what we're saying is if there's data there go ahead and grab it by the ID based on the iteration and remove it so it basically won't remove an item until we have something to replace it so this is gonna solve part of the problem and I'll show you what I mean by this so if we remove this item what's happening here is we're replacing it with the last item on the list so our first list right here let me refresh this again our first list is it has five items in it or a first array has five items if I remove it it now has four so it didn't remove this last item so this last item actually gets added in twice so to solve the second part of the issue and by the way if you notice you don't get that flash basically that little glitch that we saw girl so it's fixing that at least so what we need to do to fix this is outside of our build list I'm going to go ahead and create basically a snapshot of our list so up here I'm just gonna say list snapshot and I think I'll put it up here just to make sure that we can actually use it and keep consistent with our global variables and the sole purpose of Lists snapshot is to always have some kind of reference to what our data look like before so I'm gonna try to explain this as simple as possible but basically we set the value of list to the new data that we have and after the loop we're gonna go ahead and set list snapshot to whatever we had in the list but before we actually change the value of list snapshot what we're going to do is run a conditional and we're gonna say if and set that up if if list snapshot dot length is greater than the list that we currently have so the list that we were just that we just got back from the response it's a list of length so if the old list had more items than the new list it means that there are going to be extra rows like we saw here and we need to go ahead and remove those so our new list has two items now but the last item didn't get deleted so that's what's happening here and this basically lets us know hey go ahead and continue on and delete the rest of the items so I'm gonna write a little conditional and I'll just explain what happened after so we're just gonna grab or I'll try to explain as I go so we'll set var I and that's going to be equal to list dot length so we're basically going to grab the list the new list at the last index so we're gonna grab the length and we're gonna set that to I so if our new list is three we're basically going to start off there and we're gonna start a new loop to delete the rest of the items so we'll say when I is less than list snapshot dot length so when we're still smaller than the old list let's go ahead and grab the rest of the items and remove them so we'll grab document dot get element by ID and let's go ahead and remove that element so we then set the list snapshot to what the list looked like before we re render more so we kind of have have it stored in memory and I did mess this up a little bit and we need a new I plus plus and now if I actually go to this you'll see the effect so if it didn't make sense at least we can see what's happening here so if I just add a bunch of new items let's go ahead and submit them and if I delete them there we go so we're not having that air anymore so let's go ahead and test out that issue that I was telling you about with updating item way down the list so I added a bunch of elements here and if I scroll down here let's say I want to update this and I want to be able to still see it as I updated so we add it into the form and that's actually the reason why I made this fixed right here we add it into the form and we just say updated we submit that it gets updated without that that little glitch occurring and that data being rendered or the data still being rendered but the list in the way that we're rebuilding it is allowing us to see it happen basically live without having to re render the actual form fields the way we had them earlier or the rows so we can actually go ahead and just remove items and everything should be working fine so if you're interested in building this with react we're gonna do one more video just like this build the same exact thing using that rest API that we built out and we'll finish this up with react and then I'll continue on later with jingo rest framework series so I just wanted to make sure I got a lot of requests asking to build out a real application using this so I just wanted to give you a real world example so thanks for watching and don't forget to subscribe
Info
Channel: Dennis Ivy
Views: 85,811
Rating: undefined out of 5
Keywords: Programming, Software Developer, Dennis Ivy, Dennis Ivanov, Django, Todo, CRUD, Python
Id: hISSGMafzvU
Channel Id: undefined
Length: 55min 14sec (3314 seconds)
Published: Tue Feb 11 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.