Building Custom Filters6:43 with Lacey Williams Henschel
In this video, we’re going to learn to build some custom filters for the sidebar of our list view pages. This lets us create filters that are more specific to what we need than the filters that Django builds in.
Adding searches and 0:00 filters to the admin is a great way to make it easier to find what you need. 0:01 But sometimes you need filters that work 0:06 a little differently than the ones that Django builds in for you. 0:09 This is where knowing how to build custom filters is super handy. 0:12 For example, the date filter that Django gives us for 0:17 created at is great but it only goes back to this year. 0:21 What if I want to see all the courses created in 2015 or 2003? 0:25 I need to write a custom filter for that. 0:30 So let's get started. 0:33 First, we need to create a class for our filter right here in the admin.py file. 0:35 This class will inherit from simple list filter, which is named really well. 0:41 It's the class that Django provides for us for, you guessed it, simple list filters. 0:46 So right down here below the inlines, let's just go ahead and 0:53 return down a few times. 0:57 And create this class and we'll call it YearListFilter, 0:59 and it will inherit from admin.SimpleListFilter. 1:04 Then we need to decide what the title of our filter is called. 1:10 This is what will be coming after the word by, so if we go over here 1:14 we can see we can filter By created at or By is live. 1:21 So since we're gonna filter by year created, let's just call it, year created. 1:26 That is simple enough. 1:32 Then we need to add in a value for the variable parameter name which is 1:34 the name that gets used in the URL whenever we use that filter. 1:39 So in this case if we clicked on the year 2015 in the URL, 1:44 we would be able to see a particular name value here. 1:48 So right here in the URL we see is_live. 1:52 That's what we are setting whenever we set parameter name. 1:55 So let's just call it year so that whenever we click on something we 1:59 will be able to see year equals 2016 or whatever we chose in the URL. 2:02 Now we're ready to start coding our filter. 2:08 The first thing we need to do is add a method called lookups and 2:11 this will create the clickable links in the right hand side bar for this filter. 2:16 So lookups takes in self, request, and model_admin. 2:21 And then it will return whatever we want to show up in the sidebar. 2:29 So in this case, we'll return a tuple for what goes in the sidebar, and 2:33 we'll just manually add the 2015 and the 2016. 2:38 We could, of course, do a look up on our model instances and 2:41 find all of the years that they have and just use those. 2:45 But for the purposes of simplicity we will just go ahead and 2:48 manually add the 2015 and the 2016. 2:52 So we'll just type in return, and we open a tuple and 2:55 then it's a tuple of tuple, so we pass in strings for 2015. 2:59 And one of these will go in the URL and one of these will go in the sidebar. 3:04 And then 2016. 3:08 And we close our tuple. 3:16 So the first element in each tuple are what goes in the URL. 3:20 So whenever you click on the 2015 filter, the URL will contain a query string that 3:25 says year from our parameter name equals 2015 from our lookups. 3:29 The second element is what actually appears in the side bar. 3:35 Now, in our case, since we're just looking for a year, there doesn't need to be 3:39 a difference between the first and second element in each tuple. 3:43 But theoretically, there could be. 3:47 Finally, we need to add a method called queryset that will return all of 3:49 the objects that fit the parameters of our filter whenever we click on it. 3:54 So queryset takes in self, 3:58 request, and queryset. 4:03 And this will have some pretty straightforward logic. 4:07 So what we're looking for is if the value we click on is 2015, 4:10 then we want to get all of the courses that were created between January 1, 4:14 2015 and December 31, 2015. 4:19 And then we'll just repeat the same thing for 2016. 4:22 So if self.value equals 2015, 4:25 then we will return our queryset, whatever that is. 4:30 And to get the items in our queryset, we'll filter by created_at. 4:37 And remember we're looking for everything that was made on or 4:43 after January 1st, so greater than or equal to date. 4:48 And then whenever you're using date, you know that it goes year, month, day. 4:52 And actually since we're using date we should import date. 4:56 So let's go ahead and do that. 5:00 So from datetime import date. 5:02 All right, now back down here we add the second half here. 5:06 So we have all of the courses that happened after January 1, 2015. 5:14 And now we need to get all the ones that happened on or before, 5:19 so less than or equal to the date of 2015, 12, 31. 5:24 And then we just wanna repeat all of this but 5:30 replace the 2015 with 2016. 5:36 Let's save that. 5:48 And now, the very last thing we need to do is add this 5:49 YearListFilter to the filters that we have for the CourseAdmin. 5:53 All right, let's refresh our page and see what happens. 6:03 Okay, so we have all of the courses that are live or not. 6:06 So just all of our courses. 6:10 But now we can see all the courses that were created in 2015. 6:11 And we have this year=2015 up in the address bar. 6:15 Or the courses that were created in 2016. 6:19 Pretty cool? 6:22 This is a handy filter to have, but the logic for selecting 2015 and 6:24 2016 was really similar. 6:29 It violates the dry or don't repeat yourself principle, doesn't it? 6:31 As an extra challenge to yourself why don't you see if you can think of a way to 6:36 make the code that we just wrote more reusable. 6:40
You need to sign up for Treehouse in order to download course files.Sign up