Django & HTMX App - HTMX form submission | Query Optimization with django-debug-toolbar

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi guys and welcome to the next video in the D Jango and HTM X Series what we're going to do in this video is expand upon this page that we built in the last video and this is a page that lists out all of the user transactions and we have a small form on the right hand side and this allows us to filter transactions by a particular income type or expenditure type so if I filter that we can see that the table of transactions is filtered down to only income type transactions now at the moment what we have is a form that is submitted and it sends a normal request to the back end D Jango will then handle that request and it will return a response and that response is a new page so this is essentially reloading the page and regenerating the entire page from scratch now what we want to do here is we want to move this to an HTM X based setup so when we click this filter form we want to send an Ajax request to the back end we don't want to reload the page and we want to get back a response which is an HTML partial a hyper media response and we want that to be swapped in and to replace the existing table in this case with the new data so let's get started building that if you remember from the introductory video in base. HTML within the head tag here we have a script here that links to HTM X on the CDN so we have access to HDMX in this project what we're going to do is we're going to go to the form element in this transaction list. HTML so let's scroll down to the form element and I think I've went past that here it's here and instead of sending a normal get request we're now going to use HTM X and we're going to use the HX get attribute now what we pass in here is a URL that we want to send the get request to and I'm going to use that transactions D list URL along with jango's URL template tag here and that's going to reference this URL in the URL patterns and that's going to call this view here called transactions list so that's going to send the get request and it's going to use an Ajax request behind the scenes so we're not going to get that page reloading effect instead we want to get a response and swap that into the document and that's going to replicate the kind of functionality you would get in a single page application but of course the benefit is we don't have all that complexity of react or VJs now what we're going to get back is a partial and we're going to build that up in a second but what I want to do now is set a target for the response now we can do that by setting an element here an attribute called HX - Target and we can set that to a selector in the document now the selector I'm going to use is one called transaction container now you notice here that we have a div and at the end of the previous video we added the ID of transaction container to that div now what this is doing is it's wrapping the entire table so this table of transactions here is being wrapped by that div and if we look at where this Dev is defined and scroll down this is going to replace that table with the cont content that we're going to get back from Jango so that's what we're going to set as the target let's set that ID of transaction container and because it's an ID don't forget this symbol here and finally what I want to do is set HX D Swap and we're going to set that to Outer HTML and that's going to replace the entire element and all of its children now we need to change the view that's called here for transactions Das list so we're going to go to views.py and now we need to handle things slightly different so rather than returning the entire transaction list what we're going to do is return a template fragment or a partial and to do this I'm going to start by installing a package called D Jango HDMX so let's go to the documentation for D Jango HDMX and as you can see this is some extensions for using Jango with HDMX and we did a video on this topic it should be appearing on the screen now that was a deep dive into what Django HDMX offers what we're going to do to start with is go to the installation section and you can install Jango HDMX using pip install and we're going to do that now in vs code so if we go back to the terminal and we expand this here we're going to run pip install Jango HDMX and that's going to install that into the environment now what we need to do next is go to our settings. piy file and we're going to add Jango HTM x to the installed apps let's get back to the documentation it's very simple we can copy this and paste it in here and I'm going to add a comma after that and we're going to follow the installation instruction F here jangle HTM X comes with a middleware and that's the HTM X middleware class now we're going to copy this and we're going to add that to the middleware setting so back here in settings. pi we're going to scroll down and right at the bottom of the middleware list I'm going to add the HTM X middleware and I think that might be all we need to do and by the way the HTM x middleware what that's going to do is add a bilon property. HTM X to jango's request object and as a side note if you want to install HTM XX into your project without using a CDN you can follow the references on this page here and there's a link to this in the description of the video it's recommended to avoid using a CDN to include HDMX what you can do instead is you can use something like npm or if you want you can just download the HTM XX Javascript file and then put that into your static files directories and then if you use the static template tag you can reference that within the head tag of your base template now we might do this at the end of this video but for now I'm going to stick with the CDN now that we've got Django HTM X in the project and we have this HTM X middleware we can go back to views.py and what we're going to do in this view here is we're going to check if the request. HTM X property evaluates to true and if that's the case we're going to return a different template partial here so I'm going to copy this render statement and I'm going to paste it into the F statement and then if we don't have request. HTM X evaluating to true we can just return the normal template because that means that it's a normal request for this given page so we don't need to return a template fragment it's only in the case of an HTM X request now one other thing to note we're going to use Django HTM X later in this series so I'm not installing this just to use the HDMX property we will use some of the additional functionality in that package later in the series so let's return a template partial here in the event of an HDMX request I'm just going to paste this in here so it's in the partials directory and it's going to be a file called transactions container. HTML so let's go to the partials directory and we're going to create that file now and we basically want to move the entire transaction container into this file so what I'm going to do is go back to the original transactions list template and I'm going to scroll up here and this div here with the ID of transaction container and remember that's the HX Target element we want to move this div and all of its children into the par template so what I'm going to do is copy this div and we're going to copy everything inside of it I'm going to cut that out of this template and we're going to move that into the transactions container and I've sorted out the indentation so the entire transaction container is now moved into this partial template and that contains the table with all of our transactions and it also contains the form that we defined and that's at the right hand side of the page now if we go back to transactions list that means that what we origin had is basically gone from this div here and we're left with an empty div now what we want to do is include the template fragment here when the page is first rendered so we can use Jango include template tag for that and we pass in the path to that template there so when the page first loads it's going to include that by default but when we send the HDMX request to the back end we only want to return the hyper media content that's in this template fragment so we don't want to return the entire page as it we just want to return this data and this should be populated with the filtered transaction query set so all of the filtering in the view if we go back to views.py this should all still be done no matter whether it's an HDMX request or a normal request so let's verify that this is now working if we save all of these files and go back to the browser what I'm going to do is reload the page and you can see we're getting an error invalid filter add label class now the reason for this if we go back to transactions container if we go down to the form we're using the add label class template filter and that comes from Jango widget tweaks now we are using jangle widget tweaks now within the template partial so we're going to remove the load widget tweaks directive here and we're going to paste that into the partial instead and we need to do that right at the top of this partial so load widget tweaks and that's going to give us access to that add label class template tag and as well as that we can also use the render field template tag so let's let's try this again if we go back to the page and refresh the page we're still getting the table we still have the form on the right hand side but we're now separating this out into a partial and what this means is that when we send a request here when we submit this form it's going to do that using HTM X as you can see here so the page is not refreshed instead that's sending an Ajax request to jangle and jangle can then handle that and it's then going to return the template partial because this is an HTM X request and if we go back to the server that means that this block here this if statement is going to evaluate to true and that's why we get back the template partial here as you can see in that render statement now what we can also do is go back to the developer tools on the browser and what I'm going to do is change the type here to an expense and when we hit filter you can see that what's actually sent is an xhr request now an xhr request that's an Ajax request so what HTM X has done when we add these attributes to the form as you can see here when we add HX get it's going to then send that get request as an Ajax request to jangle so you're changing the mechanism from which the form is submitted from a normal request to the back end with a normal response to an Ajax request and that request is going to return a response that contains HTML content and you set an HX Target attribute on the form here and that's going to tell HTM X where you want this returned HTML content to be swapped into the Dom we've set it here to an element with the ID of transaction container and when you swap that content into that element we have an HX swap attribute as well and that is an attribute that can allow you to customize how that content is going to be swapped into the document what we've got is outer HTML and that means The Returned HTML is going to entirely replace the target element and all of its children we're going to see examples of other swap techniques later in this series but for now let's finish the video by showing how to bring HDMX into our local application and instead of referencing it in a CDN as we're doing here on line 17 we're instead going to add it to the application so we can go back to the Django HDMX documentation on the installation page and this section here will be linked below the video what we're going to do is download the HTM x file from the CDN so let's go to this link here and that's going to take us to the latest release of HTM X and we're going to download the minified HTM x file here if we view that raw in the browser and copy this what we can do is go back to our application and in fact I'm going to go back to the D Jango HTM X installation page and what we're going to do is we're going to add it to a file called HTM x. min.js and that file is going to be in a static directory now we have a static directory in the starter code it's in this directory here and we're going to add a JavaScript folder in that directory and within there what we can do is create a new file and it's going to be called HTM x. min.js and I'm going to paste the contents of the code from that CDN into this file so we have the file locally we don't need to go over the network now to fetch that data we now have it locally and we can close the HTM x. min.js file now the next step is to use D jango's static template tag in order to reference this HTM x. min.js that we now have locally in the St itic directory so at the top we've already loaded the static template tag and we can use that here within the source of this htx script so rather than linking to a CDN we're going to remove that and what we're going to do in here is use the static template tag in Jango and what we're going to pass here is the path to HTM x. min.js from our static directory so that's going to be in a JavaScript subdirectory JS and then within there it's going to be HTM x. min.js let's now save this and we can go back to the browser and I'm going to go back to this page here and this is our application I'm going to refresh the page and we're going to make sure that that HTM x file is being loaded by looking at the network tab if I refresh this again you can see we're getting the 20000 response is able to fetch HDMX from our local directory and it's going to use that now instead of using the CDN link so let's just doubly make sure that this is working we're going to select expenses only and we're going to filter the table and as you can see that's working without a page reload if you look at the network Tab and select income that is still sending an xhr request so that's all working fine I want to finish this video with a very small optimization and to do that we're going to look at jangle debug toolbar and you can see this here that was part of the starter code and what I'm going to do is refresh this page and we're going to look at the SQL queries that are being generated you can see we have 23 queries when we load that page and we have 20 similar queries and the reason for this is due to the lookup of the category forign key so why is this happening if we go back to our models.py file to start with we have a transaction model it contains a foreign key to the category model and that's this one here that contains the category name and what's going on is the classic n+1 problem we did a video on that that should be appearing on the screen now you can check it out for more information but in this video we're going to very simply fix that problem if you look at the transactions container that we have here and we go up to the table we have a reference to each transactions category within a for Loop that's looping over a set of these transaction objects now the problem is that the transactions have been fetched along with the foreign key to the category and when we look over these transactions here and reference that foreign key Jango is then going to perform an extra query for every single iteration of this for Loop and that's definitely not what we want when we render this table but there's a very simple fix here we can use the select related function in jangle and that's going to do an SQL join on that forign key when it's performing the fetching of the transactions so essentially in one query we're also going to get back all of the categories that are attached to each transaction and because this is a foreign key actually it should get back the single category that's attached to that transaction so it's a very simple fix like I said we're going to go back to views.py and it's this here the transaction filter that we're using that's the Django filter filter set and we're passing a query set into that what we're going to do as well as filtering by the user who's logged in is we're going to chain select related to this and we're going to select the categories from the database that's going to do that join and for each transaction it's going to Fitch the category that's associated with that transaction now what we hope to see when we go back to the page is that instead of 23 queries we're going to cut that down sign ific anly so let's refresh the page and you can see on the right hand side we've cut that down to three queries that's much more performant and this is important to understand by sending a lot of queries to the database from D Jango this can become a big performance issue and this can be a big bottleneck in the performance of your application as it scales wherever you're fetching that data and you're going to have to perform that join and display some information like this it makes sense to use select related in order to do that and that can help boost per performance and boost your application's scalability and that's all for this video in this video we've added HDMX to the project and now when we submit the form that you see on the right hand side here that's being sent over an Ajax request and The Returned content is a template partial that we're swapping into the Dom we also brought HDMX down from a CDN into our local static directory and that's going to be beneficial for security and for performance when we actually go to deploy the application and finally we optimized some of the SQL queries the orm queries that jango's sending and we cut that down significantly using the select related method now what we're going to do in the upcoming videos is we're going to add pie test and we're going to start adding some tests to this application and we're also going to generate some summary statistics and indeed we're going to look at the form on the right hand side and we're going to add some new filters and again wire that up with HDMX and we're also going to see some cool techniques such as subclassing the jangle query set object and adding some convenience methods to that object so that's coming up soon if you've enjoyed this video give it a thumbs up and subscribe to the channel if you've not already done so and if you're enjoying this content consider buying the channel a coffee we have a link in the description and thanks again for watching and we'll see you in the next video
Info
Channel: BugBytes
Views: 3,050
Rating: undefined out of 5
Keywords:
Id: _yMFB7N9sRk
Channel Id: undefined
Length: 17min 52sec (1072 seconds)
Published: Thu May 09 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.