#379: 17 Libraries You Should Be Using in Django Transcript
00:00 Do you write web apps in Django? The framework has come a long way lately, with versions three and four adopting many of the modern Python capabilities, async for example. But there are so many other libraries and apps that you can use to do more with less code and plug in new functionality. I'm happy to have Christopher Trudeau here on Talk Python to take us through his 17 favorite libraries you should be using in Django. This is Talk Python to me. Episode 379, recorded August 22, 2022.
00:44 To Talk Python to Me, a weekly podcast on Python. This is your host, Michael Kennedy. Follow me on Twitter where I'm @mkennedy and keep up with the show and listen to past episodes at 'Talkpython.fm' and follow the show on Twitter via @talkpython. We've started streaming most of our episodes live on YouTube. Subscribe to our YouTube channel overat talkpython.com/YouTube to get notified about upcoming shows and be part of that episode.
01:09 This episode of Talk Python to Me is brought to you by the IRL Podcast, an original podcast from Mozilla. This season they are looking at AI in real life. Listen to an episode at 'Talkpython.fm/irl' and it's brought to you by Microsoft for startups foundershub. Get earlystage support for your company and build that startup you've been dreaming about. Visit talkpython.com/foundershub to apply for free. Transcripts for this and all of our episodes are brought to you by Assembly AI. Do you need a great automatic speech to text API? Get human level accuracy in just a few lines of code? Visit 'Talkpython.fm/assemblyai'.
01:47 Hey, a quick announcement before we jump into the interview. Some of the ideas we discuss in this episode come from a brand new Django course that Chris authored over at Talk Python training. If you enjoy this episode and want to put these ideas into practice, or you want to just get started with Django, be sure to check out his course at Talkpython.fm/Django. Now let's dive in.
02:09 Chris. Welcome to talk python to me.
02:11 Thanks for having me.
02:12 Yeah, it's great to have you here on the show. We've worked on some projects together and talked otherwise but your first time here on talk python
02:19 Python monumental. Indeed.
02:20 Indeed. So I'm super excited to talk about Django. I don't do that much Django, which is why you're here, because you do a ton of stuff with Django. So really excited to have you share your experience. And we're going to focus on a bunch of cool little tools and apps that you can plug into Django and make it better, make it do more, and do a lot of the Django things, pull a few pieces together and make your app better without a lot of coding, right?
02:42 That's the idea.
02:43 Indeed. Before we get to all that, though, let's just start with your background. How do you get in programming and Python?
02:48 I'm an old man. Not punch card old, but single digit. Megahertz old. My dad worked for IBM, so my first computer was an IBM PC Jr. 256 memory with the expansion card, no hard drive, five and a quarter floppy, and 4.77 is really important. It made all the difference.
03:11 Did it have a turbo button?
03:13 It did not. IBM did not do that. Little bit of marketing stuff, but pretty sure my USB charger has more processing power now. But all my friends had Commodores, and so I couldn't trade pirate games with them because that's what everyone did. And Box came with this kid friendly teach yourself basic book. And so that was kind of my intro. I had one game and nothing else to do with the computer, and the first program I remember writing was a Batman logo, not copying book on my own kind of thing. And so the basic library had like, draw arc and fill in yellow, and it kind of clicked for me. And 30 years later, I was running a software department at a company that got acquired by a large firm who shall remain nameless. They just own all of your favorite movie franchises and have a road in front of it. I think you know who I'm talking about. And as part of that acquisition, the department got shut down, but we were asked to stick around to help with the transition. We had about two weeks worth of work to do and we had six months to do it in, so I had a fair amount of spare time on my hands and I used that to pick up Python.
04:18 The first script I wrote in Python was that we had a photo sharing site, and the due diligence of the transfer included looking for questionable content in that photo sharing site. And I had to, for the police investigation, go off and grab a whole bunch of stuff out of S3 and download it that belong to this one individual. So the script was kind of icky, but I was very impressed on how little code I had to write in comparison to previous languages. Part of that is Python itself, and part of it was just pip install, pip install, pip install. And it solved all these problems and I've never looked back. It's been my primary language for almost 15 years now.
04:58 What a good language. What a good choice. Who knew 15 years ago or ten years ago or whenever we all got into it that it would be so incredibly popular these days, right?
05:07 Yeah, it's grown a lot.
05:09 It's really taken off. Yes.
05:10 I just saw an article, what was it called? The unstoppable programming language or something like that from Info world. And boy, I'll even pull it up. What an interesting situation where the subtitle of the article is unstoppable. Python once again ranked number one in the Tov index.
05:59 Being number two in all of these areas very easily makes you want number one overall. Right, so I think it's the breadth more than anything.
06:07 Yeah. You talked about how the company was acquired and you had all this sort of time to kind of think about changes. I find times like that are really interesting ways to maybe refocus your career or to think about where you've been and where you might be going, or maybe whether you should turn left or right or just keep going the way you are. I've had a few like that and those are some good opportunities to take if you can get them.
06:31 Yeah, it gives you a chance to experiment, if nothing else.
06:35 There was no pressure to pick up a language. I was a manager at the time, so there was no pressure at all, period. But yes, it gives you the breathing room to go and play with a few things and get comfortable with it. And the next job I took was helping a small startup and a manager comes to me and says, pick the language, pick the stack. And it was like, okay, we'll do Python, we'll do Django. And it sort of went from there.
06:57 Good choice. How about now? What are you doing these days?
06:59 My marketing people tell me I'm supposed to call myself a fractional CTO, so I help organizations with technical decisions and software processes. So that's architecture, some coding, often it means nowadays the agile process stuff, so it's a bit of a mixed bag, tend to specialize in trying to get small teams more efficient in some tech way, either the process or the learning itself. And because of the agile thing, I've done a fair amount of teaching because often times when you're bootstrapping new teams, you got to start out with Scrum 101 and all that kind of good stuff, and that kind of led into the screencasting and online teaching world. So now I've done over 30 courses in Python and I'm still clicking along. So it's become this sort of side thing that I have that has blown up into its own thing.
07:46 I can relate. I can definitely well, cool. So part of that actually is you and I just recently worked on a course for talk Python training Django Getting Started, which there's been a six hour course. People can check it out, there's a bunch of good stuff. We're not going to really talk about that. But it kind of got me thinking. Like. Hey. Wouldn't it be great to just cover all the cool little things that you touch on here and then just in your other training. I guess people probably could reach out to you if they've got a team and they want to maybe help them shift gears. Help them change technologies or change the way they're working.
08:22 Sure. Always nice to have the pipeline full. For sure.
08:26 Indeed. Yeah. So you might be brought in to do one thing like, hey, help us django or help us change the way we're working with sort of deploying our apps or whatever. But then there's like, oh, but did you know about this tool? And have you tried this? And wouldn't it be easier if you use that? And so how about we make that the next hour?
08:43 Yes. And this kind of ties back to that. We were sort of talking about Python and the breadth of that. Right. One of the reasons it's so easy to get a lot of things going is because there are so many libraries that have been there and done that and we're going to talk about later. One of the ones that's sort of a catch all. And every time I'm in there, I'm like, oh wait, I need to remember that's in here because I keep writing that code. Right. So knowing that things are out there and finding this stuff can make a big difference in how little code you have to write. And it's always great when someone else has tested it because then not only are you not having to write it yourself, but it's probably more stable than the stuff that you're writing yourself. Or at least I'll speak for myself. More stable than my code, for sure.
09:24 Well, I think people who are getting into programming think about what is an expert? An expert is somebody who could write these crazy algorithms or implement this wild file processing stuff from scratch. And that somewhat is true, but more often the expert is the person that knows they can pip install this other thing and not have to write that. They're like, oh, these libraries exist, I know they'll work in this situation, I don't need to do this. Right. So, yeah, it's both a power. But it's also really like knowing I think knowing Python is partly knowing the libraries outside just the language.
09:57 I would say more than partly picking up a new language if you've done a few before and it's in the same vein all the grandchildren of C based languages. It's like, okay, so what's variable assignment look like? What does for loops look like? Once you've done that, a few days later you're ready to go. Knowing the depth of what's out there so that you don't have to write it, that takes forever. Right? So there's language expertise within months, there's library expertise, which is years and is constantly changing too.
10:41 Right. But on the other, you'll compare and contrast that. I feel like I've been doing this forever and I'm still learning every single day. How do you square those two things, right? It's largely what you just said. Yeah. All right, so we're going to talk about a bunch of different topics. We'll see what the final number is. 17 ish different libraries. Some of them directly plugable into Django for specific things, and some of them are just really helpful for Django. So you want to kick us off with the first one here?
11:07 So there's sort of two groups. In the first group of things, we're going to talk about our libraries that any project of a reasonable size should consider using. So these are, like you said, these aren't the Django specific stuff. And then we'll get through a few of those and then we'll get into the actual list. You should use this for Django. So this first one that you got up on the screen there, this is coverage. This measures how much of your code gets run when you run your code. So it's typically used for your user tests. And what you're trying to figure out is how much of your code has been exercised when you run your tests. So it has sub commands, one of which is run, and you basically hand it any script and it will give you an output listing of what it saw as it went along. That output listing is like a file by file listing and shows you like a percentage mark that says 30% or 50% or whatever of this file got executed in your run. And then there's a couple of other commands that you can run that will combine all this information into a report. And the report is spit out in HTML, and that gives you a fully annotated list of your code so you can go in and see, oh, there's the red line. That's a line that didn't get triggered so often, I find when I'm writing tests, it's usually fairly easy to get the easy path through, right? You're not thinking about the errors or whatever. You just say, oh, I exercised it. And then you go, oh, I've only got 75%. Well, finding if you want that, you want to have something higher than that. You go in, you look at the report, you go, oh, that red line, is that air conditioning? Okay, I need to add a test to make sure that that air conditioning is handling properly. So I often take this one and then write a little bash script that does this, runs my tests and then runs a Linter afterwards. So it's my little check in hook, right? So just before I do a push, it'll go off and run all my tests and give me coverage, and if I don't like the numbers, then I go off and fix it some more.
12:56 I think when you're learning about testing, it's important to test the happy path. But that's the one that's often kind of obvious.
13:04 You're going to know right away if that thing is broken. But it's those edge cases. What if I put a string into this input where a number like the word seven versus the number seven, is that a 500 server error or is that a sorry invalid data? Ideally even caught on the client side with HTML5 validation or something. Those kinds of things are really hard to think about. And coverage really points out, you know what, all the parts that are red that are uncovered, those are the air handling or the guarding clauses or the other cases where you're not normally going to run into them, you really need to have a test to check them.
13:39 Yeah, that's right. I'm also independent of coverage. I'm also a big fan of when bugs show up. I'm not a pure TDD guy until bugs show up. So when the bug shows up, I go and write the tests that triggers the bug and then I fix it because then I'm adding to my regression test as well. Right, so that's also to your point. It's those weird conditions that you didn't even think of and coverage, because it is only line based, you can get into trouble where the first part of an if clause passes and the second part doesn't. And so it's green, it looks like it's happy, but that doesn't mean you don't have a bug. Right? Right. So there's always a mix and go. But coverage can help you find this stuff first time through if you're looking.
14:18 I'm definitely not a pure TTD purist myself either. I find there's tests add a lot of value, but there's also a practical I just got to get some stuff done and I don't need to retest.
14:27 Everything only so many hours in the day.
14:30 Yes, exactly. But I do like this idea of like once you found a bug, if you can reproduce it with a test, you kind of pin it down so you don't play Whack a Mole and have it ever come back.
14:40 Yeah. Kind of related to this whole part of the conversation. Anthony in the audience asks he's interested to know how best to test Django web apps with Py test feels that there ought to be ready made recipes for this, given how opinionated Django is. You got any thoughts on that?
15:47 Wouldn't you know that? There's an awesome django list and it happens to be done by Will Vincent in here. There's a whole section on testing, and you've got some Pytest-django got Factory Boy for test fixture replacements, feature Flipper, Jango Waffle, that's kind of an interesting name model bakery for creating. I'm guessing the ORM models in interesting ways. And yes, people can check this out. Another related question Nick asks. I like your opinions on mocking the Orm database when testing versus actually using the database. I don't know how you feel about this, Chris.
16:22 I don't tend to mock unless I absolutely have to. I usually mock for things like, oh, we have to do something with dates, and that dates and times always cause problems because you're running the test now. For the Orm, I tend to just use tests straight into the ORM. Django comes with a lot of mechanisms like fixtures that allow you to push things into the database, and the test suite automatically will install those fixtures and wrap each test in transactions so it does it and then undoes what you did. So you're always in a known good state at the beginning of each one of your functions. So I haven't really come across a case where I really need to mock out the Orm would. Guess there's probably an argument about speed there, but I tend to get around that with things like tagging my tests. So I will tag much that are like the smoke tests, the quick one pass through, and if I need like a really fast test to run on, say, check in, then use a smoke tag, and then let the regression run overnight if you have to or whatever. So I haven't come across the need for mocking it out yet myself.
17:26 Yeah, and you can use SQL lite with an in memory database model as well. And just as part of the whole test run, you could fill that in memory version up with known good test data. The transactions will kind of roll it back each time. Right, and so just let it rip on SQL Lite in memory and then disappear into the ether of Ram.
17:44 Yeah, it tends to be unless you're doing huge amounts of work, it tends to be pretty peppy?
17:50 And you can choose how much data you put in it, right? So you can chill out on that.
17:56 This episode of Talk Python is brought to you by the IRL podcast, an original podcast from Mozilla. If you're like me, you care about the ideas behind technology, not just the tech itself.
18:08 We know that tech has an enormous influence on society. Many of these effects are hugely beneficial. Just think about how much information we carry with us every day through our cell phones.
18:19 Other tech influences can be more negative. I really appreciate that Mozilla is always on the lookout for and working to mitigate negative influences. A tech for all of us. If those kinds of ideas resonate with you, you should definitely check out the IRL podcast. It's hosted by Bridget Todd, and this season of IRL looks at AI in real life. Who can AI help? Who can harm? The show features fascinating conversations with people who are working to build a more trustworthy AI. For example, there's an episode on how the world is mapped with AI, but it's the data that's missing from those maps that tells as much of the story as the data that is there. Another episode is about gig workers who depend on apps for their livelihood. It looks at how they're pushing back against algorithms that control how much they get paid and how they're seeking new ways to gain power over data and create better working conditions for all of them. And for you political junkies, there's even an episode about the role that AI plays when it comes to the spread of disinformation around elections, obviously a huge concern for democracies around the world. I just listened to The Tech That We Won't Build, which explores when developers and data scientists should consider saying no to projects that can be harmful to society, even though we do have the tech to build them. Does this sound like an interesting show? Please use the link talk Python Fmirl to subscribe. Yes, you can search for it in your podcast player, but use the Link Talkpython.fm/irl to let them know that you came from us. The link is in your podcast players. Show notes. Thank you to IRL and Mozilla for supporting Talk Python. To me, the next thing kind of related to that is Py Flakes.
20:05 I mentioned at the end of that that I often use a linter. This is the one that I tend to go to. Py Flakes is a little is code focused rather than style focused. So when I first started Linting Python, a lot of the code I was maintaining was not Pep8 compliant. And we'd run the linters and they were just constantly screaming about everything. Py Flakes was like a nice little happy medium for us. It runs using the abstract centric trees, which means it doesn't actually load the modules, which is good, because that means you're not having to do the side effects of your actual code. And I usually use it for things like finding unused imports and weird variables and things like that. The other places I find if I've made a lot of changes across a whole bunch of files running Pyflex before I run my tests, it's sort of a bit of an idiot check, right? So the things that don't compile or whatever, it'll go through and run everything once for you. And it seems I find it faster to do that than say, run all my tests first.
20:58 Sure. This is kind of like a compiler and compiled languages, C, C++ whatever you press compile. And how does it all hang together? Sort of check that the system has to go through as a static language and we don't have that. Even if you put type hints, that's a hint, not a requirement for accuracy. And so not saying that this does type validation like MyPy, but it makes sure that your code at least somewhat hangs together, right? It's a nice quick check.
21:25 Yeah. It's a sanity checking.
21:27 Yeah, absolutely.
21:28 And there's a version of this, if you want to dig down into it, that is called Flake8 that combines Py flakes with pep8. So if you want to get all in a retentive about the code cleaning and all the rest of that, you can dig into that and essentially it's just all the same kind of commands after. It also has a nice little one of the things I always look for in a linter is the pragma that says ignore this line so that you can turn off the noise, because every once in a while there's going to be something that you want it to ignore. And I find as soon as you've got warnings popping up in your code, it starts to become broken window theory, right? Like, oh, there's a warning there. Well, now there's two warnings there, now there's three warnings there and the next thing you've got 100 warnings and nobody's doing anything about them. So I'd like to try that's exactly.
22:11 The analogy I was thinking as well. That's the way it is. Because especially in a team situation, there's some people who really bought into CI and that kind of stuff. There are other people who are not really that interested in worried whether the test will pass or worried about whether the linters pass and they're just going to go along. But certainly if that kind of stuff starts showing up, they're like, well, if it's already got warnings, I don't care about one more, you know?
22:37 Yeah. So zero warnings policy is pretty good and this kind of thing helps you find that and check it easily, right?
22:42 So for people who are listening, just put hash for comment, flake a colon, no QA on the line and then it'll skip that line. There's times when you get advice that in general is good advice, like try accept pass or something like that. You should never do that, except for sometimes in little weird situations, you're like, no, I really just need this to not care if there's an error and just keep going, and you'll be stuck with this permanent warning. This file has an error. You're catching too broad of an exception. You're like, in general, yes, but right now, I don't care. I accept that. Let's just keep going together. And this kind of stuff really is great for making those warnings go away.
23:22 And you can tie it into your PR process as well. So if I'm doing a poll review for something you've done, where you've put this, we can have a policy that says, there better be a comment above it that explains why you're allowed to ignore it in this session. So it becomes sort of two kinds of flag. It's a flag for py flakes, and it's also a Py flag for your code reviewer to go, oh, we should explain why.
23:43 Is this a valid case? Yes, we do. This is the generic. So let's put a comment that says, yes, we meant to do this, rather than, I was just too lazy to fix it.
23:51 Yeah, that's a really good point, actually. I like that a lot. All right onto another Sphinx. The Python Documentation Generator.
23:58 Yeah. So this is a sort of bit of a left turn here. I will admit I am obsessive compulsive when it comes to comments and documentation. I did co-op in university, which is what I think they call paid internships in the US. And my third co op term was with the same department as my second. And the first day back into the office, I said hello to everyone. And then my boss says, there's a bug in the code you wrote last term. Go fix it. And if my name had not been at the top of the commit, I would have sworn this was written by somebody else. The code was just hideous. And this is where I learned the whole comments are for other people is only half right. Sometimes you're that other person, like, eight.
24:35 Months later, just shifted in time. Yeah.
24:37 So I've become very attentive about it.
24:41 What sphinx is a mechanism for taking your py doc comments and turning it into documentation. And so if you were writing your comments already, it gives you a couple of little formatting tags that you should take advantage of. But once you've done that, it isn't really much more effort than just, say, writing the comment. And then you can write this script and it will spit out documentation. It's based on Restructured text format. So that's the Rst file, which is similar to Markdown, if you're used to that. And it includes things you can do, basic type setting, like bolding and that kind of stuff, tables. But one of the things I find I use a lot is you can highlight references to other parts of your code. So. If I've got a class that I'm using, here an object that is some sort of class. If I note it properly in the comments when the documentation is created, I can click a link and it'll take me through to it. So you can always find the cross references. Yeah.
25:39 That's fantastic.
25:40 It generates all sorts of different kinds of output. Personally only ever use the HTML, but it does EPUB man pages late. If you want to spit out some PDF and some other things as well, come with a sort of a quick start command that builds all your cookie cutter files for what you need. It also allows you to intermix, in general, Rst files. So if you want to write, say, a how to guide separate from your code, but then suck in some documentation from your code, it allows you to mix and match that.
26:09 So as an example, tutorial or installing or something.
26:12 Exactly. Yeah. So I often will write although Markdown is the most common format for the Read me file on GitHub, I use Readmerst. And the reason I do that is because I usually use that same README file as the intro file in my Sphinx stock. So I essentially just say, oh, go grab that Readme.rst, pull it in here as the title page, add a little table contents flag on the bottom of it, and the next thing you know you've got some documentation.
26:39 Yeah, that's really fantastic. It's great when you can get your work to multiply automatically and obviously you've.
26:47 Got to have been in the habit of doing this kind of stuff anyways, but if you were, adding a little bit of a rigor to how you're writing the comments helps a lot and I find particularly with things like API's right. Because you should be writing that doc string anyways, that says this is what the call is, these are the parameters and what they mean. And it turns all that into a PDF document that you can hand off to managers or whatever or put up on your web page or however you like to do that.
27:12 For those who are not a fan of Restructured text, there's the Myst Markdown version or plugin. So you can do Markdown as well these days.
27:22 I have to check that out. I haven't played with that one yet.
27:24 Yes, it's pretty neat. You can even do inline Restructured text within your markdown. Like Markdown markdown. Oh, I need something a little bit more complicated. There's a way I don't remember what the syntax is, but there's a way to inline a little Restructured text excellent. And then fall back to Mark down. Yeah, a little bit of an escape.
27:41 And then embed your HTML inside of your Restructured text inside of your markdown. It's turtles all the way down. Excellent.
27:49 The other thing, there are companion plugins for this as well. So one of the other libraries that I use is something called a Sphinx RTD theme, which is a Read the Docs style theme and plugs right in. And essentially it allows you to generate your HTML looking like the Read the Docs site. And if you combine that with a Git hook into Read the Docs, you Read the Docs will get automatically updated every single time you do your push up to git so, nice little combination.
28:15 Yeah, that's pretty cool. I do find it sort of meta that the Sphinx Read the docs theme is hosted on Read the Docs.
28:26 All right. P-U-D-B. Is that the right I have no.
28:29 Idea how you're supposed to pronounce it. I always say puddb, but that's fine.
28:33 Puddby. Well, I do feel like a lot of these projects, like this one, if you have too much of an acronym or you're too clever of a name, you really should put up, and here's the MP3 of how you say it.
28:43 Okay. There you go. Yes.
28:45 I loved that answer with Linux.
28:47 Hi, my name is Linus, and this is how you spell Linux. And I couldn't understand his accent and it didn't clear anything up. It was fantastic.
28:54 That's funny.
28:55 I think I've mentioned upfront that I'm old. So a lot of my early career was spent on Unix systems, Sunspark systems, that kind of stuff. And at the time there was this whole war between VI and Emacs, the wars over, I think, Vs code won. But I picked VI because it was the only thing guaranteed to be installed on any of the systems I was telnetting into. And so I'm still very old school using them to this day.
29:18 Yeah, I mean, you just said the word telnet. Come on.
29:21 I'm keeping it. It was telnetting. It was pre SSA.
29:24 I know. Now, hold on. Now, did you do like Archie and Gopher before telnet?
29:28 A little bit of gopher.
29:30 I was never on an Archie system. I did a little bit of Gopher. Yes.
29:33 It could even go more old school enough. Okay, yeah, great. So maybe these days you're SSHed in, but same basic idea, right?
29:40 Same basic idea. So why am I babbling about this? Well, what this means is because I use an editor rather than an IDE. And of course there's another place where you'll get letters because you can do everything in Vim script. So it's an idea as well. But I tend to just use it as a letter editor.
29:54 What that means is I tend to use a standalone debugger. So Pudb is one of those. It's a standalone debugger. I'm not sure why, but I've never been a big fan of PDB. The one that comes with Python. Part of that is because it's based on GDB, which I never liked either. I just need to see more screen, more code on my screen at the time. And so this is a two week program, which is Text User Interface.
30:20 And if you want to, again, shout out to the old folks in the audience. It's got a very boreland turbo feel to it. You can see the screen and the text that you're working on. And then there's a couple of little side windows with your stack and your variables and set breakpoints all the things you expect a debugger to do. And if you're stopped at a breakpoint, you can open up a reple and it gives you full context of where you are, just like you would with inside a PDB. So I find oftentimes I'm doing more debugging in the reple in context than I am actually in the debugger. Now, why this is a big deal for me is, let alone the local. If I were using PyCharm or whatever. I can work locally. This will work anywhere where I can SSH into. So because it runs over the terminal, I can get into a machine. I can use this and have it work. And it means I'm using consistent environment across all the places I go. So I don't try to sell this to other people. When I manage teams, I don't say you will use this, but it tends to be my go to. And I like to tell people that it's out there because you never know when you have to do that remote stuff.
31:20 Yeah, a lot of times it works on my machine and you get the certification even there, it works on my machine, and then I go to the server and it doesn't work. And I can't really figure out why, especially when you're setting up a new environment, you're like trying to run the web app now and Micro WSGI over here and it just won't start or something like that. Right. So the ability to get a little more insight over SSH is pretty cool.
31:45 All right, I think this may be our last no, second to last general library is talks.
31:52 Yes. So this is a wrapper for all your tests. So it essentially builds virtual environments based on a quick little configuration file. So, give you an example. Let's say I've got a line that says Pi Brace 37383 9310 Django 400. It knows how to split that apart. And we'll do all the combinations of running Python three seven, with 438, with 400, etc and etc, etc. E. And it creates a little virtual environment for each one of those combinations, and then runs all of your unit tests inside of that virtual environment. So if you're doing library support across multiple Python versions or across multiple, say, Django versions, then you can mix and match these with just a few lines inside of a configuration file, and it will go off and run all of this. And those virtual environments are created locally and cached. So, although the first time it runs, it's dreadfully slow because it has to pip install all of your requirements in each one of those environments. Once that's set up, it just leaves them there, which means first time hurts, and after that it's not too bad.
32:56 What are those trade offs between? I want an absolutely clean from scratch reproducible thing.
33:03 Also when I get my job done. So if you're going to test across five different versions of Python, maybe don't try to pip install something like microwsgi or other things that have to compile for a great long while. Just leave it there, because it does.
33:17 Compile and leave it, let it do it, go get dinner, come back, and just never delete that virtual environment ever again.
33:24 Yeah, I suspect it has multiple levels of caching as well. Like, if I pip install something and it's exactly the same version, it'll still be cached even on my machine. Even if I recreate the virtual environment.
33:34 There's levels of it. It essentially just creates a I'm trying to remember. I think it might even be VM, it might be dot talks, I can't remember. But it essentially just creates a directory and creates a directory inside of that for each one of your combinations, and then pip installs into that virtual environment. So when it runs, the next time, it will do upgrades and things like that. And if you need to, you can just go in and RMRF the directory and blow it away if you're running into trouble and need to start from scratch.
33:58 It sounds interesting for a web app. It sounds super useful for a library package.
34:04 That's where I tend to use it. So we'll talk later about one of my little bits of self promotion here. But I've got a couple of Django libraries that are out there, and I support three six through 40. I haven't got around to four one yet, and three or four versions of Django in it. And every once in a while you'll run into something that just doesn't work in some version that you think is generic. And it's become a lot easier since I've dropped support for 27 because there was a lot more crap having to deal with that. But that's how you catch those things.
34:32 Yeah, absolutely. The last general one here is Pillow.
34:36 This is semi general.
34:37 In case you're sleepy, you're programming too long and you just need to take like, a little bit of a nap or what's going on here?
34:42 That's what it's for. That's right. Pillow is for sleeping. It's also for image manipulation. So I don't do a lot of graphics stuff. My Batman logo not withstanding. It was very early on in my programming career. But in fact, Django has a semi dependency on this. You don't need it out of the gate, but if you're using certain features in Django, you do have to have it installed. There's a field in Django which is the image file field, and it uses the Pillow library to make sure that the files that are associated with it actually are images. So this is a really deep, really cool image processing library and I tend to just skim the surface of it. I use it for image and I use it for a couple of libraries as well that deal with image thumbnails, but otherwise I don't really touch it. But it tends to be one of those things that if I go through all of the virtual environments set up on my system, I'm finding out it's installed in a lot of them. So it's one of those, it's kind of common that because I don't do a lot of image stuff, it's not something that I'm playing with a lot, but it's very powerful. So if you're into this kind of stuff, this is a great library to play with. And if you're not, you may want just the surface level pieces for some web things like thumbnails.
35:54 If you're running a website that accepts, say, image upload for example, yes, you obviously need this for the Django ORM field, that's the image type. But you could also say if it's too large, let's just resize it. Or you can size it to the same size all the time. It drives me crazy when I go to sites, they're like, this image is 1500 by something and we only support 1280. Like just resize it then.
36:19 I've also used it in some command line scripts which will create like two or three versions of an image that is in the static files, right? So it'll automatically go through and like you said, okay, we've got our master, that's 1500 by 1500 and it'll go create some extra ones or whatever and you run a command and it'll run through all your static files and check that there's two or three size versions or that kind of thing. So again, if you're playing with the web, size is important, right? Yeah.
36:45 For example, if you want to have icons for your web app that can be saved to iOS home screens, they want all these different sizes from like 512 down to 64. And if you're doing retina or high resolution, you can have different ones that get swapped in and out. It would be really nice to just automate all that, right?
37:03 That's right.
37:05 This portion of Talk Python to me is brought to you by Microsoft for Startups Founders Hub, starting a business is hard. By some estimates, over 90% of startups will go out of business in just their first year. With that in mind, Microsoft for Startups set out to understand what startups need to be successful and to create a digital platform to help them overcome those challenges, microsoft for Startups Founders Hub was born. Founders Hub provides all founders at any stage with free resources to solve their startup challenges. The platform provides technology benefits, access to expert guidance and skilled resources, mentorship and networking connections, and much more. Unlike others in the industry, Microsoft for Startups Founders Hub doesn't require startups to be investor backed or third party validated to participate. Founders Hub is truly open to all. So what do you get if you join them? You speed up your development with free access to GitHub and Microsoft cloud computing resources and the ability to unlock more credits over time. To help your startup innovate, Founders Hub is partnering with innovative companies like OpenAI, a global leader in AI research and development to provide exclusive benefits and discounts through Microsoft for startups Founders Hub, becoming a founder is no longer about who you know. You'll have access to their mentorship network, giving you a pool of hundreds of mentors across a range of disciplines and areas like idea validation, fundraising, management and coaching, sales and marketing, as well as specific technical stress points. You'll be able to book a one on one meeting with the mentors, many of whom are former founders themselves. Make your idea a reality today with a critical support you'll get from Founderhub. To join the program, just visit talkpython.FM/Founderhub all one word the links in your show notes. Thank you to Microsoft for supporting the show.
38:57 This one. I'm going to vote this next one here as probably the best icon of all the things we're going to talk about. It's the Django Ninja.
39:06 Yes, they've done a good job with it.
39:11 There's a special flavor of marketing to open source projects, isn't there?
39:14 Yes, there is. Yes. I think it's called none.
39:19 We could talk for hours on why it's called the GIMP. Anyway, I find that because I'm a Django guy, I don't have a really strong need for single page applications. A lot of the work I find I end up doing Django templates is good enough for many of the pages in the application, but then there's going to be some pages where you want to do fancier stuff. So I often use Vue JS so that I can do best of both worlds there.
39:45 This is kind of a multi page application, so those pages that require spa kind of feel to it, they have vue on it and those that don't, I just use generic 1.0 web style stuff. So in the 2.0 world you need Rest APIs and enter Django Ninja. This is what it does. So it sits on top of a Django view and essentially restifies the view. And when I say on top, I mean that literally. You actually use decorators, so you write a view, decorate it with an Http method like Get or Put, and then that view outputs JSON instead of your usual HTML. The library is built on top of Pydantic, so it relies heavily on the types to help it define the JSON that comes out. You write a little schema file that says the names and types of the fields for the JSON output and it's got a schema that is based on top of Django models. So this works a lot like a model form if you've ever used one of those. So let's say I've got a Django model called a Customer. I can create a schema called Customer Out that inherits from Ninja's model schema. I create a subclass called Config, which is kind of like the Meta subclass in Django and it sets the model attribute to point to the customer. And if I want to use all the fields in the model, that's it. It's basically just the three lines. And you can customize that like model form. You can say don't use all the fields, only use these fields. Or you can add fields. If there's things like say you want a field called name that combines first name and last name, you can build something that computes that so that doesn't actually use the model directly. So oftentimes you end up having to write a couple of these because you often need the inbound and the outbound to have different fields in it. So a common practice is to have your schema for Customer be called say, Customer Out or Customer In. There's nothing that enforces that, but that's how they do it in their documentation. And that kind of just sort of picked up the habit as you go along.
41:46 It's so tempting sometimes to think, oh, we can just exchange the same model inbound and outbound in so many ways. That just doesn't pan out. Even if you're using something like Beanie or SQL model or something where literally the Pydantic model goes in the database as well. Often that's not even the same thing because for example, your inbound Create user, you want a password, your response, you'd never want to send the password directly back. You shouldn't even know what it is.
42:10 The ID field is the most common thing, right? Like every model has got one. And there's hacks you can do to say oh, if it's zero, it's a create and that's a common way of doing things. But for Django ninja, what I often just do is just leave it out. And because they're objects like anything else, you can inherit it, right? So you can start with the in and then add the ID to it. So there's ways around it's what it comes down to.
42:31 The Django ninja can be plugged into an existing Django app. It's not like a separate thing that I run that is also correct.
42:38 Like Django, it's actually just stuff that sits on top. It's got its own routes. So essentially you're building django views but you're decorating them with the ninja. And when you decorate it, it automatically collects all of those underneath one path in the Earls file. So you set up a router, usually you set it to say something like Slash API and so back to that customer example I was using. If I added a view for Create Customer, I set it to the Customer path and because it's decorated, it automatically ends up under/api/customers. So it takes care of a lot of that for you.
43:12 It looks like it also has Async support as well, which is pretty neat.
43:16 It started from scratch with the Async IO. I'm not 100% sure of this, but I think there's a couple of former DRF guys on here and I think it was a rewrite from scratch with Async from the beginning and Pydantic, so I think it's sort of the next generation. The key writers weren't in the DRF, they obviously took a lot of learning from what was there and what works.
43:37 It's pretty familiar to fast API type of programming, and it has a lot of uses of type hints. For example, you have an API function that takes a delay, it says it's an integer. I suppose it probably actually parses that and validates and so on.
43:51 Yes, and it's particularly useful as well, because by the time you're getting things down your web string, everything is string, right? Like when you post it, it's all coming up in the string. So somebody somewhere has to go, oh, that's supposed to be an int, and try to convert it. So it takes care of a lot of that kind of stuff. And in fact, one of the reasons there's so little coding in this, particularly with the Schema definitions, is because if you've already got that model file, it knows the django field is a text field, or as a Boolean, or as an integer, and it goes, okay, I know what to do with that. Right. So essentially it's building on top of that stuff that's already there for your existing code.
44:27 That's really cool. And basically so much of the validation has already happened by the time it gets to you. If you're much closer to the right answer, you have to check so many.
44:35 Things, much less code you have to write.
44:36 Yeah, for sure.
44:37 And if that's not good enough, on top of all of this is it comes with a web based debugging view, so it lists all of your registered calls. You can go and click on things. Authentication is required for the call, and it's got a whole bunch of stuff in the back end for that as well. You can click through and say, okay, I push this button and paste in my key, or hit the login button in my Django and then use it that way. So it allows you to sort of see all of this, and it includes in it the output in curl. So as you're using the debugger, you can copy and paste the line into your terminal and then run it in curl. It's a quick little tool for helping you sort of figure it all out. Pretty powerful.
45:14 It even has an interesting sync to Async adapter decorator to allow you to work with the ORM. Yeah, and it migrated along.
45:22 Shouldn't be as necessary now that 4.1 is out, because that was one of the major changes in Django. 4.1 They added Async to the RM yeah.
45:28 That's really a big deal.
45:30 Yeah. I actually remember one of the comments I saw on Twitter after four one came out was, oh, the Ninja guys are going to love this.
45:36 Yeah, sounds like it. All right, Julio asks, is this as complete as Django rest framework? And Nick Harvey says it looks lighter than Django Rest framework. Maybe give your thoughts and then we can maybe pull up the next topic.
45:50 Why don't we punt, seeing as the next one is the Django Rest framework and we can talk about it as we go along. The short answer is no, it's definitely not as complete. So the Django Rest Framework or DRF to its friends is Ninja's Granddaddy, and it, for a long time was the go to Rest library in Django. Like Ninja, it breaks things down into serializers. That's the equivalent of a schema and then views and routes. And like Ninja, it supports decorators, but it also supports classes. But because it's older, it doesn't support the type mechanism. So you have to do a little more boilerplate code to get this going. You have to do a few more things with the serializers.
46:29 I was going to say it tends to favor a class based approach. I'm not sure if that's true. When I write with the DRF, I tend to use the class based approach. There are other mechanisms in there, but it seems to be the one that felt natural for me there. It has a concept called a view set class, and this is really where it shines because you define an object, which is an endpoint, and then you can say inside of that end point, I want to do list and create and retrieve and update and destroy. And you tie that into your query set and it does all of those things for your object. So back to my customer example. I could build out that customer endpoint, and then I can say, I want to use, list, create, and retrieve, and it will allow me to create a customer or list all the customers or get a specific customer. And it does it based on mix ins, so you can mix and match which of those choices you want. So it's sort of this composing kind.
47:19 Of mechanism or sort of an observation here. To be fair, I haven't done much with DRF, but it feels to me like a lot of what you're getting with ERF is like, I have a database table, let me do the Rest things to it. Like, I want to be able to do a get against all of them or get against an idea and get individual ones. I want to be able to do a post and maybe create one where it seems like it's very structured around Crud but over API. Is that accurate or not?
47:48 There are ways around it. So the concept of serializer does not have to be tied to a model. But this is a tool for Django, so it's not really a surprise that it's kind of tied to the models. And for the most part, even with Ninja, I find 80% of what you're doing over the Rest API is mapping to your database models in the first place, particularly if you're doing it for something like react, because the things in your database are usually what you're showing up on the screen. So it usually tends to map fairly easily. And there's enough depth there that if you need to introduce new fields or do something custom, it doesn't handcuff you. It does allow you to do a lot of this stuff easier though. So, like, if you are sticking with things that map nicely to your database, then it requires far less code is what it comes down to true? I guess to get back to that sort of question, ninja is definitely lighter weight. It definitely, I find, requires less code than the DRF because it takes advantage of things like the typing, which DRF is older, and it didn't exist, and it was compatible with Python Two, and some of the stuff for those type pieces weren't there. DRF has a much richer output listing. So if I were going to need something that was not JSON based, for example, over Rest, I might go back to the DRF. So it's got mechanisms for either through it or through plugins. YAML XML message pack excel even latex. Right. So there's libraries that go with these libraries that make this sort of connect these things together. So, yeah, there's a lot of depth here. The only place that the DRF makes me really nervous and is the permission mechanism. I have shot myself in the foot a few too many times doing it. It's fine by default, but then as soon as you start mucking with it a little bit, it seems to open up a whole bunch of things. You have to make sure once you start playing in that space that you do it correctly and test properly. Otherwise you could have gaping holes. Ninja seem to be a little more locked down by default, so I kind of liked that. But that could just because I'm missing toes from playing with the DRF over.
49:51 The years, you know what the guns look like.
49:54 Tisha I think this is probably in reference to the Django ninja. It looks similar to fast API. And how would you compare them?
50:00 It's a lot of sort of similar kind of concepts. And in fact, between Fast API, the typing mechanisms. Is Fast API directly based on pedantic or just deeply influenced by it?
50:14 I feel like pydantic became very popular because of Fast API, but they're separate projects. Okay, separate maintainers.
50:20 Ninja is built on top of Pydantic, so they're all being inspired by the same thing and trying to solve very similar problems. So it's not surprisingly that people are seeing yeah, exactly.
50:29 And at the bottom. Of the Django Ninja site. It says this project was heavily inspired by Fast API. My feeling is, like, if you're already doing Django and you want to add APIs and you like Fast API, this might be a really good option because it brings so much of a similar model, but you don't have to now maintain two apps that run separately or version separately, all that.
50:49 Yeah. I also find it's got a little bit of a flask flavoring as well. Right. As to how some of those pieces and again, that's the same thing past API, using the decorators, using the types. Right. So it's a similar kind of influence, if nothing else.
51:03 Yeah. Very neat, I think. All right, Jango Gropelli, what's this one for?
51:08 All right, so a little bit of a tangent here for a second. Django is named after a jazz guitarist named Django Reinhardt, and he was often a duo working with somebody named Stefan Grapeli. So if you're looking for a name for a library for Django, Grapeli is a good fit. So now Grace got a name.
51:28 What does it do? This is actually a reskinning of the Django admin. So the grapelli folks have taken advantage of the fact that the Django admin is built on top of the Django templating mechanism, and they've rewritten all those templates using a new style. The style still feels a little dated, but not quite as dated as the Django admin. So it's a step in the right direction. It does logical things like a lot of the top right hand corner reset password view page. A lot of that stuff gets moved into, like, little drop downs and that kind of thing. The coloring is a little more consistent. It uses a footer. So, like, the actions are always in the same place. It just generally feels cleaner to me. I often use the Django admin for my back end support. People don't tend to use it customer facing, so folks who are trainable and I find that when I've used it with them, grapeli feels better for them. It feels a little more intuitive. So really it's just a skin, but it's a nice skin and it's a really easy install. You have very little. You have to do a couple of changes to your settings .PY file, and it's all done for you. Yeah.
52:36 Also, it looks like you hear skin, you think, oh, it's pretty. But it also seems like it adds more functionality. Like, it adds autocomplete for foreign keys and relationships. It adds like a tiny MCE, which is rich text editor. It adds reordering through drag and drop. Those are a little bit more than just pretty. Right.
52:56 It's modernization of the interface is really what it comes down to. Yeah.
52:59 Very cool. So another random Django bit of history to go along with the musicians was created in Lawrence, Kansas, right?
53:06 By the newspaper. That's where I went to college.
53:10 Right. Down the street from the home of Django around the same time frame.
53:14 There you go.
53:14 Right. All right, so what's up next? Import export. So it's like a distributor? It's going to make some money off of selling Rugs or what's the deal?
53:22 Rugs. Yes, sure. Rugs.
53:25 All right.
53:26 Unlike Grepeli, where you have no idea by the name, this one is a little better.
53:32 It might have an idea what it does. Right.
53:34 Less creative, more straight to the point. Like the Utilitarian name, I can import, I can export stuff from Django. Okay, that's exactly how does it work, though.
53:43 Not just a database dump. Probably something more interesting than that.
53:46 So it's built on top of Tablet, which is a Python library for tabular data formats. And essentially it maps things out of your orm to whatever tablet can handle. So that's excel JSON YAML pandas HTML jira TSV ODS CSV DBF. And I even know what some of those acronyms mean. It's essentially your go to place for spitting stuff out, like Ninja. And like the DRF, it has this what it calls resources. This is like our schema. And it essentially does that mapping thing again. So you can say, I want to take this model and I want to map it to this mechanism. And then you just run it and say, export this to JSON, and you'll get it in JSON. Export this to YAML, and it'll, export it to YAML. There are mechanisms inside of the sources similar to what I was talking about in Ninja and the DRF to do. Compositing. So if I want a name field, which is based on first name and last name, it'll combine all those things and give that to you together. One of the things that I like most, I haven't used this library a lot, but when I have used it, it's because of this feature, which is it integrates nicely with the Django admin. So you essentially can build one of these resources, let's say back to my customer example. Let's say you want to be able to import customers. You can essentially define the resource, and then you add a mix in to your customer admin object, and it automatically gives you an import button on the client screen. And when you hit that import, it will upload. You give the CSV file, it gives you a little screen that says, oh, this is the data that's coming in. And you can say, yes, I like it, and it'll put it into the database, and it's smart enough to know the difference between creates and updates. So depending on whether or not your ID field is blank, this is back to that zero things we were talking about before. It will actually update things that are there. So if you've got a situation where you've got a client phone book or something that's maintained through some other system and you need to keep them in sync, this is a quick and easy way to do that. Throw it together with, say, a management command and stick it in a cron job and you can constantly push these things through.
55:51 It might sound really simple, but the ability to say, hey, business person or manager or salesperson, you can just take your CSV and upload it. You don't have to bother the Dev team to add your data, that's pretty fantastic.
56:04 Actually, one of my clients is a very lightweight CMS and of course when they sign up a new customer, they don't want to have to input their customers data by hand. Right? So you can say, oh gosh, you have it in an Excel file somewhere. Great save, as. Put it in this format, suck it all the data in so it can make a big difference. Yes.
56:23 In the preview, make sure this looks good. That's also an important part.
56:26 That's a lifesaver, right? You know exactly what you're getting in there. You can check it rather than it going and running havoc all over your.
56:33 Database, which it probably would if people just randomly started uploading stuff.
56:39 And that might make your app crash. But you could use the Django Debug Toolbar to figure out what's going on.
56:43 Look at you, king of the Segways. Yes.
56:45 Oh yeah.
56:46 So the next one here is, as you said, this is the Django Debug Toolbar. So this is a plug in for Django that overlays over your views and gives you all sorts of information on what's going on in your page. The installation is a little more involved than, hey, just add this to Settings Py because you need some middleware and some static files and things. But the instructions are good though, so as long as you follow the instructions closely, you'll be okay. And once you got that going, it pops up in the top right hand corner. I think that's actually configurable. And it has a list of panels it comes with. I think it's twelve of them. And then there's a whole bunch of plugins that you can do as well. So for example, there's history information. A useful one I find I use a fair amount is the Time panel. So it shows you the breakdown of where your call has been spent. The one you've got up on the screen there right now is the one that saved my bacon all the time, which is the SQL panel. So it shows you exactly what queries were run, how long each of them took. I understand enough database stuff to just get me in trouble. Right. The Orm provides this nice abstraction that I find really helpful. But I'm aware that sometimes I'm doing things that aren't efficient in SQL or.
57:53 You don't know you're doing something inefficient or you might not be aware you forgot a join. And plus one problem where like, I thought I did one query, why are there 50 queries, 51 queries on?
58:04 So when you've got that sluggishness. You go to the time panel, you see that you're spending all your time in the sql space, then you go to the sql panel and you go, okay, so this is where it is. I'm beating my database to death. Why? And then you can figure out, like you said, oh, I need to add an index or I need to change to join, or whatever.
58:20 Right. So in the Django Debug toolbar, it has a time section that says CPU and Total. And if the CPU time is the majority, then it's your Python code. If it's not, then it's like, what are you waiting on? Are you waiting on a database or an API or go look somewhere else? Because it's not your code. Exactly.
58:37 It's an external resource that's holding it up. Right, yeah.
58:40 So it helps you sort of pull these things through it, and it's information that's available in any profiler as well, but it's there in combined with other things, so you don't have to go do it separately. So there's other ones, there things like caching, headers, signal registering, logging, the list goes on. And then it's a published mechanism for how you build your own panels. So even on the main site, there's another 19 panels with instructions on how to write your own. And if you go digging, there are people that aren't in the official list as well. So there are dozens and dozens of them out there for sure.
59:12 I'm probably in the awesome Django. I bet, I bet there's like there's a whole thing on the toolbar.
59:20 Yeah, it was right there at the top of your testing.
59:21 That's right, yeah. I thought maybe there'd be a list of plugins as well. Oh, a subset, yeah, like a sub section. But these things are really nice and I find them to be quite useful on the they've got different they got the whole list here the profiling. That's kind of cool, I guess. Also, one really quick thing you might want to touch on for everybody is it might not be best to put this in production.
59:45 I think there's a rule against turning this off in production.
59:48 If I remember correctly, it will not run if debug is set to true. It's the false excuse me, out of the box. So if you're following best practices of setting debug to false in your production environments, it won't be there. It doesn't hurt to belt and suspend that, though. I usually put this if I'm using it, I usually put it inside of my requirements dev. And I have a little hack I used to build up my installed apps that I add to it from local things, which there's a podcast in itself there as to how you configure in different environments, but I often only add this to that piece or hackishly commented out if I need to.
01:00:24 It's a little bit of a crude lever, but if it's not in the requirements TXT or py project.yaml or whatever. You're not going to accidentally run the toolbar if it's not installed, so don't install it in production.
01:00:35 Yeah, exactly.
01:00:36 Effective, right? How about some local flavor?
01:00:39 Yes, local flavor. So this package eons ago used to actually be inside of Django, and it just got kept getting bigger and bigger. And essentially this is the localization information for different countries. So, for example, the CA folder is for Canada, which is where I'm from, includes a list of all the provinces. That's what we call states. It's got a widget for postal codes, which is what we call zip codes, and social insurance numbers, which is what we call social insurance numbers, although we use a different acronym for whatever reason. So essentially, if you're using things like shipping addresses, you want local flavor. It's mostly just giant dictionaries and collections of tupels, but it's useful data that often you would end up writing yourself. And it's always nice when somebody else is maintaining it. And for any fellow non Americans listening, it is spelt without the U. I'm not sure if it was intentional when they picked the name, that the name itself needs internationalization, or whether that was just an amusing little accident, but that's what it is.
01:01:40 So even just having the country codes is great. Is this something that maybe makes sense to use outside of djangi, or is.
01:01:45 It I'm not sure how easy.
01:01:48 I've never done it. It might work. It really is just a long dictionary and collections of tuples, but some of it's kind of Django ask. For example, the list of provinces is set up so that you can use it easily inside of a drop down in a choices field.
01:02:03 Got it.
01:02:04 You might be able to take advantage of it without that, but it's formatted in a fashion that makes sense in the Django world.
01:02:09 Good to know. All right, we already talked about the import and the export buttons, but even more buttons on the admin if we want them.
01:02:16 Even more buttons? Yes. You can always do with more buttons. So I've only used this one a couple of times, but it saved me a whole bunch of work, so I thought it deserved to mention the Django admin area pretty much is mapped to your model objects. It really is just sitting on top of your orm. And every once in a while you're going to need something that you want your support staff to be able to do that isn't really directly tied to the orm. In fact, I've seen libraries out there that hack things, creating fake objects inside of the database so that they will show up in the orm properly. And instead of doing that, you use admin extra buttons. So this is really just a way of inserting views into your admin. And it's got a quick little mechanism for forms so that if you hit a button, it'll pop up the form for you. You can fill in the form and then it'll give you the data from the form as a callback, and then you can do whatever you want with it. So where I've used it recently was I had a complex account creation mechanism that has to create like five or six different objects that have to be tied together. So instead of having my support staff going in and using the admin to create each one of those separately, I gave them a little button. They fill in the form and it creates all the objects and ties them together nicely. And actually, just a couple of days ago, I added one which was sometimes I'll have in production code, like a couple of accounts that are like sample accounts that you want to reset the data to a known state so that you can hand it off to demo somebody or Quick if you're trying to sell a client or something. So this doesn't even require the form. There's a mechanism in here called confirm action, which essentially gives you the button. It pops up a little thing that says, are you sure you want to do this? And if you say yes, it goes off and calls your little five lines of code. So it's nice and clean. The form rendering is ugly is the word, but that kind of fits with the traditional traditional. It's traditional. It fits very nicely with what's inside of the Django admin. It doesn't look out of place, but there's nothing sexy with it. I have not used it in combination with Grapelli yet, so it'd be interesting to see what happens in that case. There's basically very little styling on the form, but it has saved me a whole bunch of code. And oftentimes I find when you're writing things for your support staff, they're spending 90% of the time inside of the admin anyways, so pulling them out of it for one special page is a bit of a pain. And you usually have to write a whole bunch of extra stuff on top of it because it inserts it right inside of the admin means you don't have to get them into a different place and they're in an interface that they know how to use and makes things easier. So very much like that import export. If import export didn't exist and give you that button up top, this would be a way of building.
01:04:52 It really nice and it's very decorator heavy.
01:04:55 It is, yes. Everything is a button or a view. And you've got up on the screen there, that's the confirm that I was talking about at the top. You call it decorate the view. And that's because in this case, you're inserting it inside of the actual Django admin model pieces. Right. So you have to essentially the decorators are doing the registration to say, okay, this is extra code for the admin. It's how they're hooking at all.
01:05:20 Yeah, it looks very useful. I've got a couple more. Yes, this one, I think I know the guy who created this one.
01:05:25 Yes. So this is a little bit of Blatant self promotion. This is django, all AWL like the leather working tool. And yeah, this is one of mine. If I had been aware of the Django Extensions library at the time that I wrote this, I probably should have just contributed to the Django Extensions library. It would have been a smarter thing. But at the time I wasn't familiar with it. And since then I've been maintaining this beast. It's a general collection of a whole bunch of crap like extensions that I just found. I was writing over and over again every single time I went to a client. So one of the times I was doing that, the client, I went to the client and said, let's open source this stuff. And they went, okay, great. And since then I've been doing this.
01:06:02 You sell Widgets, you don't sell Django admin extensions. Like let's make the world a better place.
01:06:07 Contribute back ideas.
01:06:09 Hurt you.
01:06:10 Big list of random crap. Right? So a bunch of mix ins, color utilities, some context proper pieces, custom admin commands. Yes. There's decorators in here that make sure that you're doing a post with JSON content so that if somebody's calling your view in the illegal way, it screams ranked models. So 12345 and gives you a little thing inside of the admin to move them up and down. Some testing tools. There's a custom test runner in here which adds a whole bunch of features for doing things like getting out information out of the Django admin and checking that the fields and the admin are correct. So really just sort of a little catch all that's out there. But yeah, it's here and I happily take PRS. So go find it, break it. If you find it useful, great. If you don't, send me a note and tell me why not and I'll fix it.
01:07:02 Yeah, lovely. It looks really useful.
01:07:04 I'll stop with the shameless promotion after this one.
01:07:07 I'll keep going. These are good.
01:07:08 This is Django Airplane. So I used to have to do a lot of traveling when I was consulting. And being on a plane is a great place to get some uninterrupted 4 or 5 hours of coding in unless you're coding on the web. And particularly in the olden days when you didn't get WiFi on the planes. And even now it's spotty and expensive.
01:07:27 You can't really count on it.
01:07:28 Yeah, so what I found was if I'm using something like bootstrap from a CDN, I would get in and I'd be trying to run my Django site and be like, oh crap, nothing's looking right because the CDN is there. So this is essentially a little tag that you use anywhere where you would use an Href for links or style sheets or whatever and then there is a setting that defines the mode of the system. And if you're in build mode, any time these tags find it, they'll go off. They'll grab the content, and they'll save it to the disk and just runs the page normally. And then when you're in cache mode, instead of trying to get to the Internet, it pulls it off of the disk. So it's nothing terribly complicated, but it solved a particular problem that I was having a lot, and now that I'm not really traveling, I'm not touching it as much.
01:08:17 But if folks travel less, I don't know, it's kind of weird.
01:08:21 Yeah, there's been a few changes. Life has changed.
01:08:24 There have been changes. Although I did travel recently in a pandemonium. So if you want madness, you can go back and try to fly. Yeah, so this is really nice. So basically you say airplane instead of a static ref to a CDN, you say Airplane and then the reference to the CDN and either it just passes through or it can download and then pass through. Or you can say, I'm in this development mode, I'm either at a coffee shop or I'm traveling, or whatever, and just let me another good use case. Not just airplane, even though that's the name, as if you're at a hotel with notoriously bad Internet and you're traveling for work and you got to get a presentation or new version ready for the morning. That can be a super frustrating experience.
01:09:02 It essentially moves anything that's normally on your Internet down to your hard drive if you've tagged it properly. And there's a couple of management commands as well, so it'll tell you what's in your cache and how to see it and how to wipe it out if you need to. So there's a couple of little utilities, but like I said, it's one of those libraries that is simple. Doesn't do a lot, but solves a particular problem. So if you're having that problem, yeah, go for it.
01:09:25 Fantastic. Your example is for CSS. Can I leverage this to, like JSON API somehow? Like offline some API calls or anything? Or is there not really a way to fit it together?
01:09:36 I don't think it would work if it's a straight URL that was always coming back with the same value and it was hard coded, it probably shouldn't care, but yeah, it would depend on how you were using it.
01:09:49 Yeah, sure. Last one. I think you always put last security. Right. Just kidding.
01:09:53 Okay, we're skipping ahead. Got it. No problem.
01:09:55 Are we skipping ahead?
01:09:56 I had Django Extensions next.
01:09:58 Oh, yeah. I think I just didn't open that one.
01:10:00 That's fine. I kind of touched on this one when I was talking about Django one this is a collection of things that probably should just be built into. Django is really what it comes down to. There's a whole bunch of different areas. Again, it's this huge hodgepodge. So there's extra tools for the admin, more management commands, more signals, template filters, extra model fields, job management. It's a very lightweight job management, but if you're not at the level where you want to use Celery or something like that, this might be good enough for you. Some model mix ins, permission mixins, extra validators, some utility methods. The one I use here all the time, particularly when I was learning Django Ninja and I was trying to understand how the router works, is a management command called Show URLs. It will show you all the URLs you've registered, what their keywords are, and how to call them. So it's a nice little introspective kind of thing to work through backwards.
01:10:55 Got another management command called Run Script, and this one is so useful that I had the exact same thing in Django All. Again, as I said, I should have just looked at this library first. And the idea of Run script is it gives you a Django context for running a Python script. So this is kind of like the management shell command where it gives you inside of a Django context, but it does it for the script that you're running.
01:11:18 Oh, that's cool. So things like the database are initialized.
01:11:23 I find I generally use it if I'm debugging right. So if I've got three or four things I want to do in the database. And I need to run it three or four times until I figured out what the problem is. Rather than constantly doing that in the reple over and over again. You stick it in the file. Run the script. Look at your debug. Or use it in the debugger. Of course. Is the other thing there. Because you can step through that a lot easier than you can say inside of a repl. So a lot of good stuff here, and it's one of those libraries that I find every time I look at it, I'm like, oh, I have to remember that's there, and then I forget. But you always have to sort of go back and dig through it. So it's a good little toolbox.
01:11:56 Sql div look cool for probably three migration.
01:12:00 There's three or four sql commands in there that will tell you how your migrations are, how they've changed, how you're managing them, what it's doing to them. Django has since added a couple of things that are similar to it inside of the core library, but these are definitely more powerful. So if you're trying to figure out what's going on with your models, there's some interesting stuff in there as well.
01:12:19 Yeah, fantastic. All right, maybe that brings us to django-allauth
01:12:23 This is it. This is the last one. So this is django-allauth. This is your go to place for authentication. It has a series of workflows in it that are your typical user management. Things like sign up, email addresses, email verification, password resets. And so I don't usually use it for that. I use it for the thing that most people use it for, which is it's got this hook for your social media account authentication. So most social media sites use either Oauth Oauth2. And so if you've ever been on one of those web pages that says you can sign in or create an account with your Facebook account or your Google account, this is a plugin that allows you to do that inside of your django space. They have over 100 different providers. I stopped counting. I just gave up after a while.
01:13:10 Most of them are overlays on top of OAuth2, but there are also some that are custom as well. And what happens is when a user signs up using one of these, it still uses the standard Django user, but then it creates an associated object. And the advantage of the design is it means different users can use different things. I can sign in using Facebook, you can sign in using Google or what, GitHub or Google, but we still end up with the same user style account inside of the database. But the other advantage of it is you can also associate multiple things. So say you were writing a site that wanted people to be able to log in through GitHub or GitLab but also wanted to be able to tweet, where you could not necessarily allow logging in with Twitter, but you could allow them to authenticate through it so that you could tweet on their behalf. So it allows you to start connecting and play with all those things.
01:14:00 The workflow is plugin. Try that again. The workflow is plugable as well. So there's hooks inside of the sign up process. So let's say you've got some questions that you need to ask the user when they sign up, like extra information that Django doesn't normally have. It's got a flow for that that helps you with it. So really, really comprehensive library. The only thing I find that's challenging with this really has nothing to do with the library itself. It's just that third party authentication tends to be messy.
01:14:27 You are always dealing with tokens and provider sites and all the rest of it and you're going to register your.
01:14:34 OAuth application at exactly angel list.
01:14:38 Did you do it right?
01:14:39 You're always going to be in this space of did I screw it up? Is it the token that's not right? Am I not hooking the library incorrectly? I always find it's a little finicky. Now once you get it going, it's fine, but it does tend to be a little cumbersome getting there.
01:14:53 Yeah, it's a little magical in the traditional sense. It can just work amazingly. But if it doesn't, I just don't know what the incantation I'm supposed to give it is because it won't do the thing.
01:15:03 You're debugging something that is somebody else's responsibility, so you're not getting a lot of information out of the host. System usually.
01:15:10 Yeah, and often it's encrypted and signed and stuff doesn't match. It's like, how are you supposed to know how it doesn't match anyway? But that's the story of OAuth and OAuth2. Not the library's problem. Right.
01:15:23 The library makes it a lot easier. It's just like you said, there's still a level that is painful.
01:15:29 It swims in complex water. One thing that is kind of nice here is you can unroll your OAuth as well. You can say, I did originally sign up on GitHub, but I just want to make a password from my account now to let you drop that out, which is, I think, kind of cool.
01:15:43 I think it was a very smart architectural decision to continue to use the Django authentication mechanism underneath. It means from a support standpoint, you don't have to worry about a lot of things. You can still see them inside of the admin. You don't have to worry those pieces. And like you said, if something goes wrong with somebody's Facebook account, you don't lose anything. Basically, they can send your support email, and you can send them a password, reset off of a primary account, and rehook them up another way, which is a thing of beauty.
01:16:09 Yeah, that's great. All right, well, I would say we're a little overtime, but it's been a super interesting list to talk through with, so maybe call it a wrap on however many topics. We came up with a whole bunch of cool ideas for doing more Django and Python web apps in general, so thanks for that.
01:16:25 How could you do it?
01:16:26 Yeah. Now, before we get out of here, I got to answer the two questions.
01:16:29 Well, I've answered one of them already.
01:16:32 Get right to code. What editor do you use?
01:16:35 Yeah, so I'm Vim, and for those who are taking the course, I used PyCharm there, so you don't have to understand antiquated. Speaking of magic, you don't have to follow along there, so I did use PyCharm there, but Vim is still my.
01:16:46 Standard and then notable PyPi package. It can be any one of these you want to give a shout out to. We really kind of answered that question a bunch of times, but if you want to give a shout out to something else as well, I got something.
01:16:55 Else for you, which is Aschematics. So I do a lot of Tui work, and I'm really keen on this library. They have a bunch of form widget stuff and also a whole bunch of cool, awesome, 80 style animation bits and pieces, core developers, a guy named Peter Britton, very responsive, always looking for Mrs. So. Yay, Peter. And asciimatics So if you're into this space, this is definitely something to check out.
01:17:21 Wow. Amazing. Yeah, it looks pretty awesome. All right, great example. Final call. Action. So many of the things that we've talked about here, if they're interesting, people want to learn how to actually use them repelli. Create your own admin, command a bunch of other stuff covered in your course. So check that over at Talk Python.FM. Just click on courses, find the Getting Started with Jingle course. Well done on that. Thank you so much for coming here and sharing all these. Maybe give a final call to action. People want to get started with these ideas and break some of them material to their apps. What would you say?
01:17:52 I think a lot of it depends. Anytime I'm trying to learn something new, for me, it's always about the project, right. So if you're doing something that needs the rest API, then Ninja or DRF might be the place to go.
01:18:04 If you just want to play a little bit or you're learning more about how Django works. The Debug toolbar is a fantastic way of sort of learning some of the internals and taking your Django to the next level because it's exposing a bunch of that stuff that you kind of think you know how it works. It's a nice little place to do in a tutorial, so those might be good places to start.
01:18:23 That's cool. The framework tries to hide a lot of stuff. The toolbar will reveal it what's going on. Right?
01:18:28 Yeah. Well, as good frameworks should. But every once in a while, you want to see the guy behind the curtain.
01:18:33 That's right. All right, Chris. Well, thank you so much for being here. It's been a whole lot of fun. Enjoy the same. See ya. Cheers.
01:18:41 This has been another episode of Talk Python to me. Thank you to our sponsors. Be sure to check out what they're offering. It really helps support the show. You care about the ideas behind technology, not just the tech itself. And you know that tech has an enormous influence on society. So check out the IRL podcast. It's hosted by Bridget Todd, and this season of IRL looks at AI in real life. Listen to an episode at talkpython.FM/IRL starting a business is hard. Microsoft for Startups Founders Hub provides all founders at any stage with free resources and connections to solve startup challenges. Apply for free today at Talkpython.FM/Founderhub. Want to level up your Python? We have one of the largest catalogs of Python video courses over at Talk Python. Our content ranges from true beginners to deeply advanced topics like memory and Async. And best of all, there's not a subscription in site. Check it out for yourself at training.talkPython.FM be sure to subscribe to the show. Open your favorite podcast app and search for Python. We should be right at the top. You can also find the itunesfeed at /itunes, the GooglePlay feed at /play, and the Directrss feed at rss on talkpython FM.
01:19:54 We're live streaming most of our recordings these days. If you want to be part of the show and have your comments featured on the air, be sure to subscribe to our YouTube channel at talkpython/YouTube. This is your host, Michael Kennedy. Thanks so much for listening. I really appreciate it. Now get out there and write some Python Code.