Django & HTMX App - Display Transactions | django-filter FilterSet

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video we're going to continue building the Jango and HDMX application for this finance app so in the previous video what we did was we generated some Jango models for categories and the important one here is the transaction model that tracks the user transactions so we have these models with all of the fields and we've created the database with these migrations generated and what we've also done is we've created a management script in D Jango and that management script here will generate these fake transactions and allow us to generate some data to work with so in this video we're going to go a step further and we're going to take this generated transaction data for users and we're going to display them on a page in our D jangle application so that's going to involve creating a jangle view function and a URL and it's also going to involve creating a template now we're also going to use Daisy UI and Tailwind CSS for styling up the transactions that we're going to display and then we're also going to build a filter set class using the D Jango filter package and that filter set is going to allow us to filter the transaction based on some parameters coming in from a form and the final thing we're going to do for the first time in this series is introduce HDMX and we're going to submit that filter set form using HDMX so there's a lot I want to cover here let's get started what we're going to do to start with is have a look at the GitHub repository now if you're following along with this this is the structure that I have here so we have the starter code in a folder and then for every video that I want to do I'm going to add a new folder to this repository so we have the folder from the initial video here it's called video one and that contains the final code from that video I've cloned that locally and what I'm going to do here is I'm going to copy the video one folder and you can do that in vs code by just copying that and then we're going to paste it in here and I'm going to rename this folder to video 2 so if you want to follow along from where the series was in the previous video that's the way to do that now what I'm going to do is just open the video 2 directory in VSS code and we're going to work in this directory throughout the rest of this video so I've now opened the terminal here and activated the virtual environment from the previous video and let's get started with displaying transactions on the page now what I'm going to do is run the Jango development server here and once that's running we can go to the Jango admin UI and remember we created a super user in the previous video so if you want to access the UI you can do that and what we have here is a bunch of different models within different applications and notice that we have some from D Jango allo here for social accounts we're not going to do anything with that at the moment if you have any interest in that drop a comment below the video what we're going to look at is the transactions that we have in the database now as you can see this is the stringified version of these transactions and it tells us whether the transaction was an income or an expense and it tells us the amount for that transaction along with the date and the user now the point of me showing this is just to show you that we have now got 20 transactions in the database and they're all tied to the user bug bites so we now want to create a view in the Jango application that's going to show these on the page so if we go back to the application here we're logged in as bug bites but we need a way to see these transactions so let's get back to vs code and we're going to start by creating a jungle View and that view is going to fetch the user's transactions and display them on the page now at the top here I'm going to bring in a couple of imports so just underneath the render function I'm going to import the login required decorator from D Jango and I'm also going to import the transaction model class now we have the index view that's serving a template called index.html let's go down below here and we're going to create another one and I'm going to call this transactions list and as always in Django it's going to take the request as a parameter and we're going to fetch the transactions from the database so I'm going to use the transaction model and what do we need to do here we need to call doobs do filter now importantly if you have this kind of financial app you don't want to be displaying transactions from other users so we're going to filter by default here and we're going to only get the transactions that are associated with the user that's logged in now that's going to be a request. user property that's going to tell us who is sending the request and that's either going to be an authenticated user or it's going to be what's called an anonymous user in D jangle but this transactions list page should not be available if you're not logged into the application so let's copy the login required decorator and we're going to decorate this view with login required and that means that request. user is guaranteed to be a user that's registered and authenticated and therefore to filter the transactions by that user is not going to cause any issues we know the users going to be in the database because they're guaranteed to be authenticated so that's going to return the transactions I'm going to create a context dictionary here and we're going to create a key called transactions and I'm going to copy that value and we're going to reference those transactions query set that we pulled out of the database and the final thing to do is return a template so I'm going to copy the render function from the other View and we're going to paste that in here and what I want to return here is a template that we're going to create in a second called transactions list. HTML and we're going to add the context into that and after we created The View we're going to go to urls.py within this application and I'm going to create a new URL here so let's give it a path of transactions and the view that we want to call is going to be views. transactions list and that's the one that we just created here and we can also give that a name so I'm going to give a name of transactions Das list and if you pass a name to the path function like this what it's going to do is it's going to allow you to reference that URL in the jangle reverse function and also in the URL template tag in jangle so we now have the URL and the view here what we're going to do is create this template called transactions list. HTML so I'm going to do is go to the templates directory and in the tracker application we can create this particular template so what this is going to do is it's going to extend the base. HTML so that's tracker sb. HTML and that came with the starter code for this series and then we Define a couple of blocks here I'm going to define a headcore title block and I'll end that just below here and what this is going to say it's going to basically be the title of this page and I'm going to give it the title of transactions list if you look at index or sorry base. HTML here the head title is just going to allow you to generate a title for the page if we go to the browser and we look at the title here it's what appears in the tab at the top so that's the title the important block for actually showing the transactions is going to be defined in a Content block and we can end that block below and within this block we're going to write some code to display the transactions that we have in the context in this Jango template in an HTML table so to start with let's go to index.html and I'm going to copy this header one tag we're going to display a header on the transactions list page and I'm going to paste that in here and let's change the text content of this instead of the welcome message this is going to be the transaction list page so let's paste that in there and what I also want to do here is I want to show an icon and that should be an icon that somehow displays that this is a list page so what I'm going to do because we're using Tailwind is go to this site here and it's called hero icons I'll leave a link to this in the description of the video what we're going to do is search for an icon and I'm going to put in list as the search term here and we get back a set of icons that we can very easily add to our D Jango templates now I'm going to copy the SVG here and go back to vs code and in the H1 tag I'm going to paste that in just Bel before sorry the transactions list text here so we have an SVG and that's the first child of the H1 and then we have the text which is essentially the second child and we're going to display these using Flex classes so for the H1 what I'm going to do is go to the right hand side here and I'm going to use display of flex and in Tailwind to do that you can add a flex class and I'm going to use items Center here and also some margin bottom for this H1 so that's all we need to do we've copied the H1 from the other template and we've added the flex and the margin bottom classes and we have this icon that we hope to appear on the page so let's save this and go back to the page and I'm going to go to the URL at/ transactions I'm going to see what that looks like now you can see the search icon here sorry the list icon and we have the text here just right next to that now I'm going to add some margin to the end of this SVG so let's go back here and I'm going to go to the right hand side now the SVG itself has these two classes we can add a margin end and let's say of two here if we go back to the page now and refresh you can see we get a bit more space in between the icon and the text now below this we want to actually build the table now what we're going to do here is go back to the daisy UI documentation and again there's a link to this below the video and I'm going to search for the table component let's search for that and you can see some of the classes that we can use with Daisy UI so the component class is table and then we have some modifiers such as table zebra and also different sizes that we can apply such as table small medium and large so let's go back to VSS code and what we're going to do just below this header one tag is we're going to create some more HTML here so I'm going to check first of all do we have transactions in the context so we're going to use a template if statement in jangle and don't forget to end that just below here that's going to check if we have transactions being added so this context here is trying to find transactions for the logged in user but of course the user might not have uploaded anything now after we've done that check we can go back to the template and we're going to Define here a table element and I'm going to give this a class of table and that's the component class from da UI now just to speed things up a bit I'm going to paste in the table headers here so we have the table head element and we're giving that some classes from Tailwind so text extra small and also text white that's going to make the text appear white as well as uppercase for the table headers and for each transaction we have a table header element that contains these headers for the date the category the type and the amount for the transaction and each one of these table headers has been given some padding here as you can see so that's the table header we can then create the table body and that's going to contain the actual data that's coming back in the context for each one of these transactions now we need to Loop over them so let's create a template for Loop and we're going to say for transaction in transactions and again just below here I'm going to end the for Loop and immediately so I don't forget and then for each transaction we'll create a row in the table and that row is going to contain some table data elements so TD elements for each one of the columns that we've defined above here so let's start with the date that's going to be transaction do date and we can close the TD element here now this date field is a field on the jangle model class for the transaction so we have the transaction model and you can see the date field that captures when the transaction occurred we're referencing that here for each transaction That We're looping over now I'm going to copy this table data element down three more times and we're now going to change the field that's referenced here so as well as the date we have the category and that's the second column the third column was for the type so let's reference that here and the final column was the amount for that given transaction so that's the table body and that's all we need to do for the table itself but what I also want to do is as well as checking if we have transactions I want to add an else Clause here so just below the table let's add the else clause and if we don't have transactions I want to send some text to the user so I'm going to paste some text into this so we have a paragraph tag with a couple of classes from tailwind and we're just telling the user that no transactions were found so let me clean this up a bit I'm going to tab the table itself over and the final thing I want to do is surround the F statement with a Dev element that's going to add some classes here and I'm going to paste these classes in so we have relative overflow X Auto and also the text white class so all of the text within the table should be white so let's tab everything else over one more time and we can close the div just below the if statement here and we're going to test this out now so let's go back to the browser and if you refresh this page we now see that we have a table of transactions appearing on the page so for the loged in user we can Now display all of the transactions in this table what we're now going to do is add some links to this page from both the homepage and also on the NAB bar that you can see here at the top so let's start with the homepage I'm going to go back to VSS code and we can go to index.html and let's have a look at the homepage again just in the application now we have some dummy text here of course in a real application you can fill that out with whatever you want for your app I just want to have a link below this welcome message here that's going to allow the user to view their transactions so let's go to index.html and we're going to find that welcome message and you can see it here so I want to add this just below the div that we have and just below these paragraph tags let's add a div here and I'm going to give this a class of border and also a class of margin bottom six and we'll close that div out so it's only going to be a div that's going to have a border and then just below that we can create another div and again some margin bottom to that now within this div we're going to create the anchor tag and we're going to pass an hre property that's going to use jango's URL template tag here and the URL that we want to use is the transactions list URL so let's copy this and go back to to this template here and it was index.html we're going to reference that transactions list and then when the user clicks the anchor tag they're going to be taken to that page and we're going to add some classes from Tailwind to this so first of all let's add font medium and we're also going to make the text white as we're going to do throughout the whole application for this anchor tag and I also want to add a hover underline class to this so basically when the user hovers over the link we want the underline to appear and that way the user knows that this is a link to another page and finally I'm going to add an icon into this anchor tag so we're going to add those Flex classes as well so I'm going to move this onto a new line and let's add flex and also items D Center and let's close off the anchor tag and we need to give it some text as well so let's give it some text now it should say view my transactions and the final thing I want to do is just add an icon before the text so let's go back to Hero icons and for the view transactions icon we're just going to search for chart here and let's just copy the SVG for the very first of these elements and paste that in here and the final thing to do is find the classes attached to that SVG and again let's add some margin end of two we can go back to the page now and that's here in the application and we should now see that we have a link to view the transactions and if we click that we are now taken to this page now we also need to add a link to the nav bar at the top now if we look at the starter code we can see we have a partials directory here that contains a navb bar. HTML and later on as we use HTM X we're going to extend this a lot and we're going to include a lot of different partials so let's now add the link to the nabar and we're only going to add that link if the user is authenticated and we're going to do it just before the logout link now in order to do this let's just copy the text for the logout and we're going to paste that in here and tab it over and we can change the text here to my transactions and also we need to change the url that's being referenced in this anle tag so let's remove account log out and we're going to replace that with the transactions list URL so if we save that and go back to the page here you can see at the top on the nav bar that has now appeared and we can also click that from the homepage to be taken to the transactions page so this seems to be working quite well at the moment we have the ability to view the transactions but notice something about the table that we have here if we look at the date for these transactions they are in no particular order what we want to do here is we want want to have the most recent transactions appearing first in the table and we want to have that ordered from the most recent transactions at the top and most distant transactions at the bottom of the table so how do we do that there's different ways we could do it so let's go back to vs code one way would be to use an order by clause in this query set so after filtering we could chain. order by onto this and we could order by that date field in descending order and that's a perfectly fine way to do that if we save this and go back to the page we we're going to see that this is now ordered with the most recent transactions at the top and that goes down to the bottom with the transaction that was most furthest away in the past now I think it's going to be common to order transactions by descending order of date so what I'm going to do is remove this and go back to models.py and this is an alternative way to create an ordering for a particular model or for the query set associated with that model what we can do and I'm going to do this just under the Thunder string method is we can create a meta class and we can set a property on that meta class called ordering and I'm going to set that to a list that contains the single item and we're going to use the date in descending order so let's save models. pi and if we go to views.py notice we no longer have the order by here if we go back to the page and scroll to the top when we refresh this page we should see that the ordering is now still maintained but this time it's being defined in the transaction models meta class using that ordering property so that's good Pro progess so far we have a page here now what do we want to do next on this page we want to allow users to do some filtering so we want to for example switch between income and expenses a user might only be interested in viewing the income fields or the expense rows in the database and something else we might want to do is filter by category so for example if we wanted to see how much we'd spent on housing or food we should be able to filter the list down to only those that have those categories and as well as the categories we may also want to to see well how much did we spend on food between these two dates so the ability to filter between two dates is also going to be important on this page and the final thing we're going to do is also get some summary statistics for example what was the total income and the total expenditure from this data and what was the net income from that data so let's say you made $20,000 income but your expenditure was $40,000 in total your net income there is going to beus $20,000 so we're going to have some data displaying that just above this table later in the series now the important thing is we're going to attempt to do all of this just using HTM X so no page reloads here when we do this kind of filtering we want to update the table and all of the summary statistics based on those filters dynamically without a page reload using HDMX so let's start simple we're going to start by switching between income and expenditure what I'm going to do is we're going to use a jangle filter filter set now and that's going to allow us to dynamically filter down the transactions based on potentially multiple parameters coming through in a get request so what I'm going to do is go to the jangle filter documentation and it's here and there'll be a link to this below the video and what this does specifically is it allows users to filter down a query set based on a models fields and it displays a form that allows them to do this now we did a video on jangle filter that should be appearing on the screen now so if you want to know more about this package check that video out let's start by going to the installation section and we can install Jango filter using pip so let's go back to vs code and I'm going to stop the Django server and paste that command into the virtual environment and once you've installed that you can go to your settings.py file and go to installed apps and we're going to add Jango filter to the installed apps so let's go to the documentation and we're going to copy this line here and we can go back to VSS code and add that to installed apps and then what we can do is we can go to the tracker application here and we're going to add a new and we're going to call that filters. Pi now we're going to build this from scratch to see how to use jangle filters let's start by importing jangle filters at the top and we're also going to import the transaction model class that we're going to be using to filter that transaction query set down based on the parameters once we've got that we can add a filter class I'm going to call it transaction filter and that's going to inherit from the jangle filters. filter set class now if we look at models. Pi if we want to be able to filter based on income or expenditure it's the type field that we want to filter on so let's add a meta class here and that's going to link the filter set to the model transaction and then the same way we do with d jangle form classes and rest framework serializers we can add fields that we want to apply to the filter set class and we do that with the meta do Fields property and I'm going to set that to transaction type and because that's the only field in this triple we can add a comma at the end here now transaction type is not actually a field on the model the field name is type so why am I adding transaction type that's because I'm going to override this so let's go to the actual fields on this filter set and we're going to define a field called transaction type that's going to be equal to a jangle filters. Choice filter so jangle filter has these different types of filters based on what the data type is or what kind of filtering you want to do and what we're going to pass here is some choices and that's going to be the transaction models transac action type choices field if we go to models. Pi that's this one here that defines the triple containing two elements one for income and one for expenses and because we've given this a different name than the model field what we can do is add another keyword argument here called field name and this will reference the actual name of the field on the model and the name of that field was type and we can pass what's called a lookup expression here and we can do that with this keyword argument and for this because we've defined the choices explicitly we're going to use the I exact lookup so that's a case insensitive exact lookup and the final thing I want to add is an empty label for these choices and we're going to see any so this is our filter set class we can use this filter set in the jangle views.py file so rather than calling this query set here we're going to replace that by using the Jango filter filter set class so let's start by importing that at the top from the filters module we can import the transaction filter and then let's scroll down down to our view function here and I'm going to replace these lines of code so let's rename this to transaction filter and we're going to instantiate the transaction filter here and we pass the data from the get request into that so let's imagine the user is going to submit a form on the front end that's going to send a get request with the data that they want to use to filter this is how we pass that form data from that get request into the filter set and then it will perform its magic and filter down the transactions based on those parameters now we need to also provide a base query set and what we're going to do is Define what we had before so basically filtering down the transactions to only those attached to the logged in user and we're also going to change what's in the context here so I'm going to rename the context variable filter and what we're going to pass in is the transaction filter set class itself and by passing the transaction filter into the context we're going to get access to a couple of useful properties on the filter set firstly the query set after it's been filtered Down based on those parameters and secondly we also get access to a form and that's going to be a jangle form under the hood and the form itself is going to use the fields that we pass into the meta class and it's going to render those out in a form on the front end so let's now see how to apply that let's go back to transactions list. HTML and I'm going to minimize the terminal here and we're going to scroll up just above where we defined these transactions and just above here I'm going to add for now a form and we're going to set the method to a get request later on very soon we're going to move this over to use HDMX but for now let's just Define a form explicitly with the get method now within the form let's define a div tag and it's going to have a class of margin bottom two and we're going to use a form control class and that's a component class from tailwind and when I say Tailwind I actually mean Daisy UI here so let's go to the daisy UI documentation now I have a page open here on a select component and that's what we're going to use because the choice field that we've got in the form that allows us to select between an income and an expense we want to show that as a select ox and we can use da UI for this we have the form control component class and then we have a couple of extra component classes here such as select and label and as before with the table we also have some modifiers such as select bordered select ghost and so on so we're going to render the form that's attached to that Jango filter filter set and we're going to give the label that class of label and for the field itself we want to render that out with the select class now if we go back to vs code let's go to requirements. text and you can see that we have installed the jangle widget tweaks package now if you're not familiar with that I've used it a lot in previous videos with HTM X and Jango this allows you to add classes directly to form fields in the Jango templates so let's go back to transactions list at the top here we're going to load the widget tweaks template TXS we can do that with the load widget tweaks directive and if you're doing this make sure that settings.py has widget tweaks in installed apps if you're following from the starter code it should already have that let's go back to transactions list and if we go down to this form that we're defining here we can now render out the form that's attached to the filter set now in views.py we set the context variable to filter so we're going to reference that here and the filter set has a form property and that contains a j form instance that's attached to the filter set and as I said the form will contain Fields based on what we Define in The Meta class so it's the transaction type field let's copy that and go back to the template and we're going to reference that here and we can use a template filter from Jango widget tweaks and that's the add label class template filter and we're going to add the label and also a text white class and remember this label class will come from Daisy UI once we've done that we're going to go below here and we're going to to use the render field template tag from Jango widget tweaks and again we're going to reference filter. form. transaction type and what we're going to add to that is some classes so let's add the class and let's give it a daisy UI select component class and I'm going to add background gray 50 here as well as text gray- 900 now feel free to add whatever colors you want here for the background and for the text within this selection now once we've added that field I'm going to paste in a button here that's going to allow us to submit the form and that button has the button and button success classes now if we go back to Daisy UI again I'm going to search for the button component here and we can see the classes here so that BTN that's the component class for defining a button with Daisy UI and button success is just going to add a modifier here and that has the success color very similar to bootstrap but this is using da UI now what I want to do at the moment is go back to vs code and save this and we're going to go back to the page here and we're going to see that well it's not working exactly as we want and one thing we need to do here is restart the jangle development server once that's restarted we can go back here and refresh and we can see the form but we can't see any transactions so let's go back to VSS code and what we're looking for here are transactions but we've removed the transactions from the context we now just have a filter and that filter has performed that filtering of the transaction qu set and we can get access to that query set directly using filter. Qs so this is checking if we have any objects in that query set and then When We're looping over them we also need to reference filter. Qs just below here if we save that now and go back to the page we should now see that we have the transactions appearing in the table now if you watched the first video you would have seen that the form is on the right hand side of the page and the table is on the left hand side so we're going to take this form and move it to the right hand side and the table should appear on the left and we can use the Tailwind grid column system in order to do this so I'm going to go to the documentation on grid template columns and you can see these classes here such as grid columns 1 we also have grid column 2 3 4 and so on and these are utilities for specifying the number of columns and a grid layout now I'm going to go back to the page here and let's imagine that we want the table to take up 3/4 of the page so I'm going to Define four columns and the table here is going to be on three out of four of those columns and the form that we have at the top is going to be on the final 1 out of four columns so let's go back to VSS code and we're going to Define that column layout now we're going to do this within this div that we've given these classes so let's go down here and Define another div here with a class of grid and as well as grid we're going to give it the grid calls for class and that's telling Tailwind that we want this to be on four columns and we can also specify a gap between each column I'm going to set that to Gap four now let's end this just below here and I'm going to add a couple of comments just below so we want three out of four columns for the table of transactions and then just below that we want one out of four columns for the form and I'm also going to add a comment just above this div here that defines the grid this is the container div for that grid let's start with the table we want to move the table into this section of the code so underneath the form where we have the if statement let's copy all of of the code down to the bottom of this F statement and I'm going to cut that out of here and paste that just into this element here and what we can do if we go to the top here is just before we look at the if statement we can Define another div here and that's going to have a class of column span three and that's what's going to tell Tailwind that we want this to take up three out of four columns and then again we're going to tab everything over once we've done that we can close off that div and then after we've defined the div with the column span of three I'm going to copy that and go back down here and just underneath this comment let's define the second grid or second column rather and that's going to have a column span of one and we can close that div as well just below and finally let's move the form that we have into this new column and we can paste that here so let's now test this out if we go back to the page and we look at this page now if we refresh you can see now that the table is on the left hand side and we have on the right the filter form that allows us to filter by income or expense now does this work at the moment if we select income here and we click filter you can see that we get back the table that contains only the filtered rows with the type of income and that will work if we select expense as well we get back only the rows where we have expenses now at the moment this is not using HDMX so each time we send a request here using the filter button it's going to send a normal HTTP request and we get back the response and that reloads the entire page so we're going to move this to HT TX and actually we're going to do that in the next video I think this one's running quite long and I actually have somewhere to go run it now anyway so I'm going to have to stop but there is one final thing I want to do here if we look at this in the developer tools and we go to the mobile view we can see that this is not responsive so the form at the right hand side here is appearing on top of the table so what we're going to do is change some of the classes that we have on the grid system so let's go back to vs code here and we're going to find the class that defines our grid that's this one here and we're only going to display this in a grid if we have a mediumsized screen or above so let's add the MD modifier here so the grid and the grid calls four classes as well as Gap four we're going to only display those when the screen is of medium size and what we can do at the start is default to the flex glasses and we're going to use flex Co so that that Stacks up from top to bottom and I'm also going to use reverse here and what Flex call reverse is going to do is it's going to change the order here so rather than the table we're going to see the form appear at the top of the page and the final thing I want to do to this div is also add a class or sorry add an ID here and that ID is going to be called transaction D container and this ID is going to be important when we bring HTM X in we're going to use that as a Target very soon in this project let's go back to the browser and we're going to refresh the page you can see that it still looks roughly the same when we are on the normal view but if we go to the developer tools and we look at the mobile view now you can see that the form is appearing above the table so that's stacked up on top and that's going to be more usable it's a better user experience if we have this application and our users are using this page so that's all for this video we have displayed the transactions in a template and we've used ajango filter filter set in order to filter down what's displayed on the page and we've also created a responsive view for this page in the next video we're going to add HTM X so that when we submit this form it's going to do the filtering dynamically using an Ajax request that HDMX is going to to control so we're going to set that up in the next video and we're also going to optimize some of these queries using D Jango debug toolbar so stay tuned for that in the next video thanks for watching give it a thumbs up if you've enjoyed the video 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 we'll see you in the next video
Info
Channel: BugBytes
Views: 4,131
Rating: undefined out of 5
Keywords:
Id: PJgBHMsM7NY
Channel Id: undefined
Length: 33min 55sec (2035 seconds)
Published: Mon May 06 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.