The Django Admin Is Your Oyster: Let’s Extend Its Functionality with Adrienne Franke

This video features Adrienne Franke at DjangoCon US 2022 in San Diego, California, USA.

The Django Admin Is Your Oyster: Let’s Extend Its Functionality with Adrienne Franke
0:31:16
Published November 3, 2022
2,324 views

The Django Admin is a great low-code tool for basic CRUD actions. However, it can do much more than that. While the Django Admin shouldn’t be used as your user-facing web app, it can be a game changer for your internal team. Whether the goal is to empower the Support team or move away from risky raw SQL statements, the Django Admin can be customized to meet the need. Throughout this talk, I will share ways you can supercharge the Admin’s “batteries included” functionality and get the most from this out-of-the-box tool. This talk is best suited for people that have a bit of experience with Django, but experience with the Django Admin is not necessary.

This talk was presented at: https://2022.djangocon.us/talks/the-django-admin-is-your-oyster-lets-its/

LINKS:
Follow Adrienne Franke 👇
On Twitter: https://twitter.com/adriennefranke

Follow DjangCon US 👇
https://twitter.com/djangocon

Follow DEFNA 👇
https://twitter.com/defnado
https://www.defna.org/

Summary

Adrienne Franke argues that Django’s admin is more than a basic database interface: it is a powerful internal tool that can be safely extended for teams beyond developers, provided it is restricted to trusted users and sensitive data is kept out. She shows how to improve performance on very large datasets by overriding search behavior, avoiding unnecessary `distinct()` work, and using `prefetch_related()` or `select_related()` for related objects. She also demonstrates custom forms and validation, save-time updates across related models, support for multiple databases, customized templates and dynamic help text, and bulk admin actions. The examples use a Mini Cooper factory and show how admin customizations can make complex workflows clearer and more useful without building a separate application.

Key takeaways

  • Treat the Django admin as a powerful internal tool for trusted users, not as a public-facing application, and protect it accordingly.
  • For large tables, profile queries with Django Debug Toolbar and optimize search results, `distinct()`, `prefetch_related()`, and `select_related()`.
  • Custom forms, validation, and `save_model()` logic can update related records and provide clearer errors before data reaches the database.
  • Multiple databases can appear in one admin by using custom model-admin methods and database routing.
  • Custom templates, dynamic help text, and admin actions can explain consequences to users and automate bulk operations.
  • Keep highly sensitive information such as PHI and PII out of the admin unless it has exceptionally strong security controls.

Summarised automatically from the transcript.

Transcript

5,938 words · auto-generated Show

Automatically transcribed, so expect mistakes in names and technical terms.

0:20

Speaker 1: So first of all, I want to say thank you so much for coming out to these talks. Um I think Jingo, like all the talks are gonna be amazing. The keynote was amazing. I'm really looking forward to it. So thank you again for coming out. I'm going to be sharing quite a bit of fun stuff about the Django admin, how to customize it to your needs, some helpful tips and tricks I've learned along the way. I've also posted the code and slides to my GitHub, so don't feel like you have to take photos of the screens. You're more than welcome to do so, but I did have it, I do have it posted on GitHub, which I will have a link for at the end of the talk when I'll be taking questions. So without further ado, let's roll into it. The Django admin is your oyster. Let's extend its functionality. So

1:06

Speaker 1: who am I? My name is Adrian Frankie. I uh yes, my last name is pronounced Frankie, even though it doesn't look like it. Um I work in the healthcare space. I work for a company called Stratizan. Um Headquartered in Nashville, which is also where I live, we make reporting software for hospitals, health systems across the US to drive better outcomes, all that fun stuff. And at my previous job, I built and maintained a Django admin app for the entire data science and analytics department. And that's where I learned a lot of these tips and tricks. I really had to kind of muck through some custom requests from people and really got to see how far you can push the admin to its limits. I'm really passionate about web development and automation and making tools better for people, making it really awesome for the end users.

1:55

Speaker 1: So you'll probably get the vibe of that throughout this talk. So the Django admin, how many people in here have used the Django admin or are familiar with it? Okay, sweet. So probably don't need to go into too much detail about what it is, but if you haven't seen it, this is what it looks like. It's basically a GUI where users can interact with the contents of your database. So you've got the authentication and authorization sections up at the top. I don't know if you can see my click. I wasn't expecting there to be two screens. But um it's got the authentication and authorization at the top. You can get very granular with your permissions in the Django admin, which is awesome. You can restrict Some users from certain areas of the app, you can make sure, like, oh, I want this group of users to only

2:41

Speaker 1: create rows in these models. I don't want them to even see these models. you can make it very customizable for you. And that's that just comes straight out of the box. And then you've also got like the individual apps from your Django project that you've registered to appear in the admin. So for a little bit of context, I made an app as if I was the owner of a Mini Cooper factory and dealer. So that's kind of going to be the context of all of these situations, all of the problems that I'm going to be kind of running through in this talk. And you can do all of the CRUD actions in the Django admin. You can create, read, update, and destroy rows here. It's very, very helpful. So a little bit more about what it is.

3:27

Speaker 1: It's it's an internal tool for trusted users, and that's really, really important. It's basically like a portal to your database. I mean, the people that work with the Django admin have this super user status where they can do Anything and everything. They could select a checkbox that selects all rows and delete them. So it's very, very important that only trusted internal users are using this app. It's a very powerful out-of-the-box interface to manage data in the database. I think Django is like one of the only few web frameworks that has a Django admin. I've done quite a bit of development with Rails. And Rails does not have anything like this. I'm not going to pit the two against each other. That's been done to death. But um this resource that Django has is incredible.

4:14

Speaker 1: I think it's it's really awesome. If you're not using it, I highly recommend that you check it out. Um and one of the things kind of where I'll break a little bit with the Django docs, which is maybe a hot take and controversial, but The Django Docs say to beware of over-customization, and I say, let's go with it, like let's do it, let's try it, let's really push it to its limits. But again, like you should not expose this as your front end for your end users. It's and the Django docs say this. I I support them. They support me on this. It's just not built for that. You know, there there's um even recommendations that people say where you should change the URL for the admin. So typically it's slash admin. You should change it to something other than that

5:00

Speaker 1: because if hackers find out that you're using Django, they will go to the admin and try to get into your system because it's like a door to your data. Um so It's not an option for your front end, but I don't think it's something that you should ignore. In fact, I really think you should explore it. It's a tool that can really empower people across your organization, not just developers and engineers, but Think like customer success, support teams, implementation teams, and in my experience the data science and analytics people have also had a lot of really great experiences with using this tool to kind of empower their workflow. flows. So with that, let's get to the um meat of the matter

5:45

Speaker 1: of Okay, some of some the snail is moving. Alright, on my screen it doesn't look like it's moving. It's supposed to be moving really slow because Django Admin is notorious for being slow. Especially when you have a lot of data. At my previous job, there are um where I learned all these tips and tricks. There's two SQL tables. One of them had about 50 million rows and the other has about 25 million. And when I originally was getting these into the admin, I was like, I don't know if this is gonna work. Um and it didn't for a minute. It if someone tried to search for something on the the Django page, the the admin page for these models It would search for like five minutes and then bring the entire app down for everybody. It was very bad. You know, there's like the instance of like, oh, it took 10 seconds,

6:32

Speaker 1: like not ideal, but it still works. This situation was this is not at all acceptable. This is actually causing a lot of problems for other people because you have to get the app back up and running. But I was actually able to implement a custom search results function that now allows the team to have like lightning fast results. And I'm going to walk you through how I how I did that. So have you all heard of the Django debug toolbar? Show of hands a little bit? Sweet, awesome. Um it's this really helpful uh I don't think it it's not in Django, but I think it should be. But you can um install its package. It displays various debug data about the current request and response. You've got A lot of things you can menu dive on, like the time it took, the actual

7:21

Speaker 1: headers and requests, the SQL stuff, which is what's on the screen here. It actually shows you the SQL that is being run when you're querying for something, when you search for something, static files, templates, like a really great amount of work. Like even if you're not doing anything with the admin, this is a really awesome tool to check. So what I did, I was like, why is this so slow? I went to the SQL section and I cannot show you the actual SQL that was run because it's like my old job stuff. But you can it it clearly there was a bottleneck. Like there was a very clear bottleneck and what was happening was Jenga was going out and getting every single related thing to the object I was searching for It was like, oh, this is related to that. You probably want, and this is related, and this is, and it just kept this going until the app was like, I can't do this anymore.

8:12

Speaker 1: So basically what I realized was that it the Django debug toolbar gave me a spot where I needed to optimize. And After some optimization, you can see what it looks like. I was able to take the query from 16,000 milliseconds to basically 10. And um I'll show you how I did it. I'm not just gonna say I did it and have you guys believe me. Um with just six lines of code, we can drastically speed up search results. So this get search results function is how Django returns the results based on your search query or lack thereof if you don't have one. And like I said, the reason this is faster is because you're specifically telling Django what you want, what the exact objects are that you're interested in, rather than Django just assuming that you want every single related thing.

9:01

Speaker 1: So basically you just set use distinct equals to false. You don't really need it to be equal to true even if the data is distinct. When you use distinct stuff in SQL just like is a lot slower. So you can just set that to false. If there is no search term, just return the query set. Otherwise, return the exact objects I want with the filter that is your search term. And that's basically all you have to do. You just have to overwrite This function that already exists and tell it, hey, actually instead of going and getting everything, I need you to come over here and just get this one thing. Um and it's just significantly faster. Another thing that is very handy for speeding up stuff is a function called prefetch related.

9:46

Speaker 1: And this automatically retrieves related objects in one batch and does all of the joining in Python and that reduces database queries for you. So this is something that you can use with the ORM. It's very handy if you're dealing with any kind of related object. I definitely recommend trying this Another one is select related and this is similar, but it does it a little bit differently. It does it on the SQL side. So it creates a SQL join and includes related fields in the SQL select statement, but it reduces databases queries as well. You're probably like, well, which one do I use? Um so pre-fretch related is kind of for a group of things. And select related is limited to single objects like foreign key and one-to-one

10:32

Speaker 1: relationships. But you can try both and see what works better. Like you're not going to break anything. It kind of just does depend on what the situation is. But those are two great things for helping to speed up queries when you have related objects, stuff like that. So the next thing I'm gonna talk about is two functions that can be very useful for customizing things. So I'm gonna start with a little scenario Let's say that when you update one row in one table, you may also want to update rows in another table based on the updates you made in the first table. For example, let's go to this Mini Cooper factory. Let's say that the price of a car part increases. You'd probably want to increase the price. of any cars that use that part because like if your motor goes up by $2,000, you're

11:19

Speaker 1: you're gonna increase the price of the car that uses that part. And with the out-of-the-box Django admin, there's no way to do that. You really can only do one row at a time with the way the admin works. Which is good, but sometimes you just need to push it a little bit further. So I've implemented checkboxes as a clever way to kick off functions that can do additional work for you if you select them. And you create them by using a form in your Django admin page and you define a Boolean field. If the box is checked, if it's true, kick off a function. If it's false, just ignore it, don't do anything. And you can really do any type of pre or post save functions here. But it's a really helpful way to just kind of make this one page in the admin a little bit more functional.

12:07

Speaker 1: And the clean function is something that'll be used in the form as well to check that the data in the form is valid. So for this example, I just made sure that all of the car parts, their price was greater than zero, because we don't obviously want a negative price or a part. But the skies are is really the limit with the stuff you can add here for validations. Um you basically just define the logic and if the data doesn't hit what it needs to it'll raise a nice validation error. And that's significantly better like raising these validation errors in your form than not having any checks and having like a database error happen. Because then you're hitting the database more than you need to. You want to make sure your data is really great. before it goes to the database. So from a user perspective, it just looks a lot nicer because otherwise you're gonna get, if you

12:55

Speaker 1: if you're using the Django admin with non-technical people, not non-technical people, you're gonna, there's gonna be like a yellow screen that's like int va invalid object and they're gonna be like, I don't know what happened, I broke the app. Whereas if you have a validation error, you can say, hey, this this type actually needs to be a string or something like that. Another thing you can do in the clean function is you can define objects here that you'll use later in the save model function, which I'm going to get to. In a second. But for this one, we're going to define two new objects. One is the price difference. So if car part price was $8 and now it's $10. That price difference is going to be $2 that we're going to carry over into the save function. And then the cars that utilize that part.

13:41

Speaker 1: So the save model is how you actually override the underlying save function to do that pre-or post-save function. And for this situation, we're going to do something pre-save before we save the object. So for every car that uses a part we're changing the price for, we're going to add that price difference to the MSRP price in the car model. And that's only if you've checked that optional checkbox. This will go once you check that and change the price from $8 to $10, it'll actually go and add that $2 to every car that utilizes that. part. You don't need to go in and manually figure out, okay, well what what are all the cars that use this? You know, what are all the objects that are related? Put in a list and then like go manually do it. This just does it for you. So you can really

14:26

Speaker 1: just try to think about how this might be useful for the people in your team that are using the Django admin. Another really fun thing you can do with the Django admin, not out of the this is kind of a common theme, not out of the box. You can't do this out of the box, but you can if you tweak it a little bit. You can have multiple databases in your app, in your admin, and just have one admin page. You don't need to make a new app or anything like that. You don't need to have separate apps for separate databases. You can do it all in one spot. And I'm not going to go into too deep detail on how to do this on the back end because this talk is focused on the admin, but some things to think of here. So by default, migrations happen on the default database. So when you want to migrate on the other databases you've defined, you need to use the

15:15

Speaker 1: database flag basically. So you say Python manage. py migrate um database equals sandbox. We'll just say sandbox is like our alternative database here that we're using. And that's how you do migrations for other databases. And then you also need to set up some custom database routing. And this, what custom database routing does basically is it ensures that the models stay sticky kind of to their original database where they live. So basically for these you say for these models Always write to this database, always read from this database, so you don't have to worry about any of that getting mixed up or anything like that. So those are the two important things. And I have a link to the docs for this in the slides, which you can check out later.

16:04

Speaker 1: But for the admin side, you're probably like, wait, what about the admin? You can register this in the admin. I'll show you how to do it. real quick. So basically in your database's dictionary in your settings file, you list all the, excuse me, you list all the um Stuff for your other database. You can list as many as you want. Um, so you just say like, oh, this is what it's called and this is how you connect to it, all that stuff. And then what you need to do is make a custom model admin class. And this is something that you'll use across your app. So you'll want to put it in like a utils folder or a common folder, something that you can pull from. Um, so you can use it across the app. And you basically say You know, use this model admin when you want to use the sandbox database.

16:50

Speaker 1: So when you when you're gonna save the model, actually go up and use the sandbox. When you're gonna delete, use the sandbox. All of this stuff, get query set. So it knows for the admin part to use this other database's settings. There's no separate admin link. All of the models that use this database still appear on your one admin homepage, all that good stuff. So then when you actually go to register this in your admin. py file, it looks really similar to all your other stuff. You just have this specific custom model admin that you define. And you basically treat it as you would any other admin. And you can see down here, there is the little sandbox situation. It appears on the same page. as all your other stuff. And this can be really helpful

17:37

Speaker 1: if you're working with different databases for different purposes or maybe different teams in your companies use different databases. It can kind of hold it all into one spot. It's a lot easier to manage. The next thing to talk about is customizing admin templates. So maybe you want to add a little bit more broader documentation to your admin pages right on the page themselves. I know that there's documentate like there's a documentation link up in the right hand corner but not everyone's gonna go there because people don't like dogs. And it's probably something that's a little bit more broad than the help field text because I know with the help text You can do that for specific fields, which is really nice, but you can't do that, there's nothing for the entire page.

18:22

Speaker 1: So you're thinking like, well, when a user comes here Do they know what to do? I mean, if they're not technical, if they're in support or if they're, you know, not saying that people in support aren't technical. Usually they're actually very technical. Just say like they don't know exactly what the database is, like what model it might be hitting, all that stuff. So you can give it a little bit more info. So what you need to do is just add the path to the templates folder. To your settings. py file and then create a folder structure like this. So you have your templates folder and then you're going to make an admin folder. And then another folder for the model that you want to add some stuff for. And then we're going to talk about the change form. So you just make an HTML page that's for the change form. And then this is what you add in that change form.

19:09

Speaker 1: It's just four lines. Basically, you extend the base change form. So it has all the stuff, it has all the fields, the forms, all that stuff. But you add a section at the top. And you define something that we will also define on our model. I'm calling it admin help text because that's what it is. You could call it awesome help text or whatever you want. It's a field that you define. It's not something that comes with Django. And then in your model, you set it there as well. So it says here, use this page to adjust the price of a car part. And that's actually what's going to appear on your change page. So now it gives end users a little bit more detail about like what exactly they're going to do when they come to this page. And this has a little bit more detail, like

19:56

Speaker 1: you have the option of expanding the price to the cars that use this part as well if you want. So this just gives a little bit more info, a little bit more color as to what's going on when you actually change. The values in these fields. Another thing that can make this one page even a little bit more functional is setting some dynamic help text. So these checkboxes that we have, we were talking about earlier, like what if we want to give that checkbox even more context? Like what if we wanted to make it even more user-friendly? What if we want to change the help text for a field depending on the actual object itself? Or maybe depending on other objects that it's related to. So we can actually do that. Because right here I'm saying like, okay, if you go and expand the price to the cars that use this part, what what are those cars?

20:45

Speaker 1: Like I don't know, is there like 50 of them? Is there one of them? This actually tells you it says If you change the name if you change the price of this widget, MiniCoupe, Paceman, Countryman, and S are all going to have their prices increase. So it just gives you a little bit of like, hey, I I know what I'm doing when I click this button, I know what it's gonna change, and um it just really helps the user. So there's actually quite a bit of not quite a bit of code, but it's like too much to put up here on one screen. Um so I'm gonna go by section by section. And basically what you do is you override the init function for your form. So this is the form, this is the init function is run before your form is shown to your users. It's the initialize.

21:31

Speaker 1: function. And whenever I was a beginner at developing, all right, when I would see args and quarks and super, I'd be like, what is that The first thing you do with this function is you use the super function, which basically just gives you access to the methods and properties of your car part form. It's just going to give you some stuff that you can work with and do some logic with. So don't be scared of that stuff, although it can be a little frightening at first. Um and here we're going to use quargs to get the instances ID. So quargs are keyword arguments. They were passed into the init function. And this is just the object that you click to go to the change page. So it's like I clicked on widget one, two, three, and right here I'm getting the ID of that object. That's really all that's happening here. I'm just using quargs to do it.

22:18

Speaker 1: Once you have the ID here, you can basically do kind of whatever logic you want. So what we do is we go get all the related objects that we need. So the cars that use this part and what are their names, and then use all of that to dynamically set our help text. So we say self. fields And then the name of our checkbox, expand prices to cars with this part, and set dot help text. That's basically all we do. And it's um a string that we add the list of the car names to. Don't forget about error handling with this. Again, you want to think about your end users and what they're seeing. Might be kind of weird if there's no Help text on this. So just kind of make sure you handle for that.

23:03

Speaker 1: Like if there are no cars that if there's nothing related, you give a little message about that so they it looks nice and they know what's going on and all that stuff. And here it is basically this from where we started with this page where you could only change the price. Now we have a little bit more info about what happens when you edit this page. You can expand the prices to cars with the part and you know what data that's going to affect. It just makes this page a whole lot more functional for their end users. And then um custom admin actions. This is pretty cool. Um out of the box there's only one admin action available and it's delete, which is really helpful. I've definitely used it quite a bit. You can check as many rows as you want

23:49

Speaker 1: and go ahead and delete them. But I bet that there are a lot more things that you all can think of that these actions could be helpful for. Like maybe you want to apply a discount to a Mini Cooper if you're running a sale like Happy Honda Days or Toyota Thon stuff like that. like that or maybe you want to hit an external API and get some updated prices for my parts. Maybe you want to refresh some data or build a dashboard based on something. You can pretty much do all of that with these custom admin actions. And they're not difficult to set up either. You basically in your admin. py file you is where you'll do it. So let's just take the example that because inflation is going up, we're going to increase the prices of our cars by a little bit. And we don't want to manually do something, or we

24:35

Speaker 1: only want to do this right now, or you know what I mean? Like this is just an example. Um, first you need to define the function, and this is in your admin. py file. You know, right above the admin itself. You basically just say the name of it and kind of what you're going to do, and then you can give it a short description. And the short description is what's going to show up in the drop-down when a user clicks So you want to make sure it's very clear what's going to happen when they do that. So for each car that we've selected in this drop-down, um basically get their base price and add 8% to it and save it. That's essentially all that we're doing here. It's it's very simple, but you could get pretty crazy with this. this stuff. So then you've got a drop down and you can actually just increase the MSRP by 8%.

25:23

Speaker 1: And it's it's very easy. You can easily test things like that. They can be very functional. You can add as many as you want. And yeah, all that stuff. So kind of to recap, the Django admin is just like an amazing tool that comes out of the box with Django. It requires very little setup if you just want the base stuff. I mean I think it takes maybe 10 seconds to get stuff. spinning in the admin. It's really amazing. But again, trusted internal users do not expose this to end users, change the admin URL. All that good stuff for security, maybe put it behind like I, you know, uh have like a VPN or something like that where you have to be on that just because it is like kind of a an open area where people can kind of do stuff very easily to the database.

26:10

Speaker 1: But really don't be scared of customizing it. I've I've was running this in production at my previous job for like a year and a half and there were no major issues. It was really helpful for everyone, even with massive tables with like 50 million rows. So, you know, go for it. Like really don't be scared of it And just be creative in your endeavors. Think about how this could help not just your developer team, but other people in your organization that may not have the time to spin up an app like this or may not want to, but may really like the functionality of it. Support, implementation, um data science, stuff like that. And then there's just so much good info online. Like I I didn't speak to some Django admin guru about this. I just learned it all by myself through people requesting things from me and I had to Google to figure it out and be kind of creative.

26:58

Speaker 1: So I hope this has kind of provided you a little bit of fun stuff to think about, like how you really can push the Django admin, all that stuff. And you know, definitely download the Django debug toolbar. I learned a lot of this from the Django docs. I think half of programming is sifting through docs to find like what you can actually do. So definitely read those and then Stack Overflow, of course. There's people ask questions about everything. So that's all I've got. Got the code and slides online. Sorry I didn't do an in-person demo. I was like, I can't do that. That's terrifying. But all of the the Mini Cooper app is there and all the code is there for you guys to dig into later. So any Questions

27:48

Speaker 2: So first I just want to say thank you. This was really good and I'm looking forward to kind of reviewing and looking for my app. The one question I had was the uh really early on the get search request I think it was where do you put that code like where do you do that override?

28:01

Speaker 1: Yeah um let me see if I can rem remember off the top of my head. If not I have the code here I can look. I think it's just in the admin. py file. I'm pretty sure it's just in the admin. py file underneath the admin that you're defining, but it's in the code where it should be So, which is on my GitHub. So, yeah. Thank you for the question.

28:25

Speaker 3: Hey, I want to second the bit about being a great talk. This was awesome. Just one question. Do you have any like best practices for handling say string fields that can be null but not blank? Like so that you know because Django barfets you the val the validation within Django barf sets you because it's you know you're trying to put invalid data in there, but null is valid But not in HTML forms.

28:46

Speaker 1: Um I don't know that I've ever run into that. Um null but what did you say? Can you say it one more time? Null but not blank.

28:55

Speaker 3: Strings which can can be null but not blank.

28:57

Speaker 1: Null but not blank. Yeah, I don't know. I haven't run into that, so I I can't, I don't know. I'm sure if I Googled for it for 10 minutes, I could have an answer.

29:08

Speaker 4: Hi, again, uh gonna echo that. Great talk. Thank you. Uh had a one quick question. So uh learned a lot about like how we can use Django admin and the use cases here, but in your experience, are there boundaries that Oh, we should look at so are there flags where if this applies to you would not want to use Django admin?

29:26

Speaker 1: Yeah, that's a good question. And um let me think about that for a second. Um I would say anything that's like really secure data, like PHI, PII, I wouldn't put in the admin. Um I would I would tightly put a tight wall around that. I I wouldn't add any of that into the admin. Um what my company worked with was not PHI. Like so Where I used to work was a company called Healthcare Blue Book. It was a price transparency company and we had a lot of claims data for people. None of that ever lived in the admin. It was all kind of the products of it, like, oh, what are these doctors charging for this price? What is the address of this facility? Like things that's not PHI would not put PHI in the Django admin. Me personally, I'm sure if you put enough VPNs and duo

30:13

Speaker 1: push Microsoft authenticators stuff behind it, like maybe it could work, but I wouldn't I wouldn't do that. Yeah.

30:20

Speaker 5: What does PHI mean?

30:21

Speaker 1: Uh PHI is person personal oh my gosh, I should know this because I work in healthcare. Um I think it's protected Protected health info. Protected health info. And PII is personally identifiable information. I get them confused sometimes, but it's it's basically stuff that you don't want open out in the open. It's very protected by HIPAA. You um have to be very careful with it. So yes, thank you for the question. I just assumed everyone had that knowledge.

30:45

Speaker 3: One more acronym, HIPAA.

30:46

Speaker 1: HIPAA, yes. HIPAA that has one P. Yes. One P. It sounds like it has two Ps, but it has one P. It's H-I-P-A-A. Fun fact.

30:58

Speaker 6: All right. Do we have any other questions? No, okay, in which case, uh thank you very much, Adrian. Thank you. Small token of thank

31:06

Speaker 1: you. Thank you very much.

Questions this talk answers

How can I speed up Django admin search on very large tables?

Override `get_search_results` to return only the objects matching the search term and disable unnecessary `distinct` work. Adrienne reports reducing a query from about 16 seconds to roughly 10 milliseconds.

Discussed at 8:12

How do I validate Django admin form data before it reaches the database?

Put validation in the form’s `clean` method and raise a clear validation error when the data is invalid, such as when a car-part price is zero or negative. This gives users a useful form-level message instead of a database error.

Discussed at 12:07

How can I use multiple databases from one Django admin site?

Configure the databases and migrations, add custom database routing, and create a reusable `ModelAdmin` that overrides operations such as querying, saving, and deleting to use the alternate database. The models can still appear on the same admin homepage.

Discussed at 14:26

How do I add documentation or instructions to a Django admin page?

Add a templates path, create the appropriate `admin/<model>` template structure, and extend the admin change-form template with an extra help-text section. Define the text on the model so users see guidance directly on the page.

Discussed at 17:37

How can I show dynamic help text in a Django admin form?

Override the form’s `__init__` method, use the current object’s ID to retrieve related objects, and set a field’s `help_text` dynamically. The example lists which cars will be affected before the user checks the option.

Discussed at 19:56

How do I add custom bulk actions to the Django admin?

Define an action function in `admin.py`, give it a clear short description, and register it with the admin. The example applies an 8% price increase to all selected cars, but actions can also refresh data, call APIs, or build dashboards.

Discussed at 23:49

Where do I put a Django admin `get_search_results` override?

Adrienne says it belongs in `admin.py`, underneath the `ModelAdmin` definition, and points to the accompanying code for the exact implementation.

Discussed at 28:01

Note: We understand that names change, people change, and bodies change. We respect each individual's journey and privacy. If you have any concerns about a video or need us to remove content, please don't hesitate to contact us. We will handle your request with care and promptly address any issues.

More videos from DjangoCon US