Learn Python with Talk Python's 270 hours of courses

#277: 10 tips every Django developer should know Transcript

Recorded on Sunday, Jul 19, 2020.

00:00 We recently covered 10 tips that every flask developer should know. But we left on a pretty big group in the Python web space there. Django developers, and this one's for you. But I've invited Bob Bell DeVos, who's been running his SAS business on Python and Django for several years now to share his tips and tricks for working with Django. This is talk Python to me, Episode 277, recorded July 19 2020.

00:36 Welcome to talk Python to me, a weekly podcast on Python, the language, the libraries, the ecosystem, and the personalities. This is your host, Michael Kennedy. Follow me on Twitter, where I'm at m Kennedy. Keep up with the show and listen to past episodes at talk python.fm and follow the show on Twitter via at talk Python. This episode is brought to you by linode. And us Have you heard about the 100 days of code challenge. It's a challenge where you write code for an hour a day for 100 days. It's helped many developers finally master programming. But it can be hard to know what to study or have resources to focus on. That's why we wrote not one but two 100 days of code courses 100 days of code in Python, which covers mostly pure Python, and 100 days of web in Python, which covers a whole spectrum of web frameworks and concepts. If you've been thinking about taking the 100 days of code challenge, be sure to visit training, talk python.fm. And check out our courses. They are the 100 days of projects and lessons with a tidy bow on top just for you.

01:40 Bob, welcome back to Talk Python To Me. Thank you. Nice to be here. Hey, man, it's good to have you back. Good to be catching up with you. You know, what we should be doing is we should be catching up in Pittsburgh having a beer. But instead we're meeting on the podcast on Skype. And that second best? Yeah, there was no pike on this year. Robin and Robin.

01:59 I know I know. You and Julian both had flights from quite far away to come hang out there and it didn't happen, did it? And then they'll happen next year. Hey, well, it's hard to see it now. But life will go back to normal. Mostly, I think eventually we'll get this whole deal figured out. But right now it's a bit chaotic. So let's just, you know, maybe check in what have you been up to? since the last time you were on? We had you on two episodes before you're on 140, which was a big one where we kind of met each other and whatnot, talking about 100 days of code projects. Ultimately, we went on to write a couple of courses, the 200 days of code for like Python and web Python stuff together. And you're also on episode 224 12 lessons from 100 days of web, which is sort of ties into that as well. So it seems like you're on with the tips here. That's a good set of topics. Yeah. Django, always on the platform. So what do you been up to? Since back then? That was

02:58 back in 2019? About a year ago? 2019. Okay, so yeah, obviously, the platform is still growing. That's all in Django. Not everyone knows what the platform is, right? So tell people about your code challenges platform and what's going on there. Because this is a place that you've been running, how long you've been running code challenges for since the end of 2017. Right? So three years of running production level Django stuff, running on Heroku and doing other interesting things. So a lot of the tips are sort of pulled out of that experience, right? Yes. Yes. So it's on their code challenge. Yes. And it's a platform where people can learn Python through practical exercises, which we have almost 290 now. And, yeah, that's pretty exciting, and learned a lot of Django there. And what's going on for the rest? Well, as you already know, I was a Python developer at Oracle, and till next week, actually, next week, which is actually three weeks ago, due to time shifting, because we speak in the future or the past or something like that. But yeah, so from the time of recording, you're just about to wrap up your time at Oracle. Yeah, yeah. And going full into pi bytes, which is pretty exciting. So Congratulations, congratulations. That's so awesome. So

04:17 I think some people would consider it a dream, right? You've made it to the point where you build something curated over time. And now it's strong enough to be your full time job, which is fantastic. Yeah. For two, three and a half years.

04:30 Is that part of that overnight success that just took 10 years type of thing? Yeah.

04:35 It's daily work, right? It's, it's a lot of consistency by just going full on that right now. Awesome. So congratulations. And thank you. That just means you're focused more on on making your platform run well, and obviously, Gordon is a business like the secret that a lot of people don't learn until they try is that running a successful software business? Is like 30% technology. Yeah. Yeah. So there's a lot more

05:00 But you still get to focus on your Jenga side and make the platform even better. So that'll be a lot of fun. Yeah, it's a platform and we do coaching. So we also help a lot of clients with with their Django. So and that's, that's really nice segue. Yeah, yeah. Awesome. All right, well, I'm looking at the notes that we put together. And there's a lot of tips that we got to go through so much like,

05:22 we trimmed it down. So we're gonna see if we keep it to 10, plus some unspecified number of bonus items as well. So when I think of Django, this first tip that you have, this is like, one of the main things that I think of is like, it comes with these building block pieces that, say, flask, and pyramid and FastAPI and whatnot just don't come with, like, admin backends. Yeah, that's where we're gonna start out. Yes. So Django clearly comes with batteries included. And some people actually don't like that, because they want to roll their own. And they think it's opinionated. I happen to like their preferences. And yeah, one of those well known building blocks is the admin interface. And it's pretty impressive, but a few lines of code you, you can just add your model and an admin.py file, and you have the complete crud interface, which is probably enough for the end user. But as a maintainer of the site, it's it's pretty convenient. And it's also very easy to extend it. So for example, taken an admin class here, you can define some search fields, which makes those fields searchable. You can have even have autocomplete fields, which they integrated with JavaScript, you can override the get query set. And yeah, it's a nice way of inheriting from the admin dot model admin class. And yeah, yeah, so it comes out of the box, just, I kind of think of it as like, Google Sheets, or something for your database, right, right, where each table is like a tab or a sheet in the workbook, or whatever the terminology of Google Sheets is. But the tabs at the bottom right? Something that I mean, not necessarily the same UI, but that idea that you have like a grid over top of it. But what you're telling me here is I can go and derive special classes that are tied to the various tables, or the models more specifically, and it lets you search different aspects of it. It lets you cool auto completion, you could also say like limit how many items come back in your search results per page. So you don't get a million or something like that, right? Yeah. Or you can do a list filter, for example. And then certain columns at the right side of the page, you can filter on them by clicking just with one line of code. So this, there's really some cool functionality. And I think maybe in the show notes, we can link to a Django admin cookbook, I use a lot, which has like,

07:46 and I might have mentioned that before, actually on pi Deanna bytes and the environment load from that book. That's like 50 pages. And yeah, very workable code. Super cool. Another thing you can do is you can write a function called get query set, and actually do things like B join or do a join queries against other things. Otherwise, you may end up with like the n plus one problem of RM is where you one query, then everything that comes back, you have to do more queries per item to try to like, fill out the details. Yeah, I will talk about that. And, and one of the tips. Yeah, yeah. Awesome. That's super cool. Let's see what else you want to say about that. I, you know, I was it you I think it might have been you, either you or Dan Bader from real Python, talking about using this to actually trigger events as you interact with this admin. Was that you? Yeah, I think that was me. Yeah. Yeah. Yeah. So tell us that. That's like, I think that's pretty related. tell people about that. That's pretty cool. We probably we spoke about that on Python bytes. Yeah, I think what we did was in one of the admin models, so for right, the safe method, and then if the object was created, and only then do a certain action, like emailing people, but in hindsight, that's probably better to do with a salary task. But yeah, it's an example how you can override those methods and do certain things. Yeah. pretty easily. Yes. Yeah. Very, very cool. All right. Number two, or a magic? Yeah. Well, Django comes with its own ORM object relational mapper. And it's kind of a proxy to the database. So you don't have to write SQL yourself. Although I am such a fan. I'm saying, well, you worked at Oracle Did you?

09:31 Actually, or in the no SQL world, maybe odms. Or some, you know, like, our might not necessarily make sense. But, you know, there's so many issues you can run into if you don't use parameterize queries, you know, little Bobby tables and all those issues. And just like if you get the raw queries back, and you pull different values, and sometimes you forget to convert this thing to an integer, and it's just a string that has an integer in it, that sort of like there can be all these little weird edge cases right now, yours

10:00 With ORM, that kind of, it's like a layer that just separates, like how your data should be transformed. I really love it. I think it's great. I know. Yeah, hundred percent work all the time, right? There's places where it doesn't. But that's not as you know, like most the time it's a it's a beautiful thing. It's Yeah, it's it's a nice abstraction, and it's way easier to use and more elegant, I would say it's how Django has it's pretty pythonic. And you have those helper methods, like, for example, get object or 404. And it's retrieved object and if not,

10:34 return a 444 exception. Yeah, exactly. or equivalent response, right? So yeah, might be exactly what you need. And you don't even it's just one method. It's a very concise, right. So if you just directly went to the objects and said, get me something where like, the primary key is such and such, you would get an exception, potentially, but it might say, an exception, which is does not exist, the model does not exist. And you don't want to tell the user, like what that's going to tell the user is 500 server error. Right? You don't stop it. And so this will translate that, basically, effectively catch that exception and raise the http 404. Which is no part of the proper response. Yeah, yeah. Sweet. The methods into shortcuts. So that's clearly like, a shortcut. Yeah. And yeah, nerves, so many things, I can highlight a few. For example, when you get an object, you can also just manually catch the does not exist. exception. Nice one is get or get on this call, or on the score, create, which if the object is in a database, it retrieves it. And if not, it creates it and returns a tuple off the object, and then a Boolean created. So I use it in a few places, too. Sometimes I just want to object and if it's not there, I want to create it. And you can do that kind of in one line of code. And then the second return a Boolean, the created you can then say, Well, if dot equals created Do one thing, or if it was not created, do you another thing and again, it's a shortcut back interesting is like a proactive, absurd update or insert. But the other way, yeah, yeah.

12:14 Yeah. Okay. The door. Yeah. Yeah, that's really cool. All right, what else is good in here, use filter a lot. And also use exclude. And then there are those neat, like English like methods like first. So for example, model dot objects dot first, or dot last, or even preparing? I read about earliest, or latest and those read like English, they do exactly what you expect them to do. Right? So the threes like, like, like by

12:45 then with the query, and for example, if you're filtering, you can use under double underscore to, for example, you have a field and then you can do underscore underscore contains, is that like a person? Like a like? percent? Like, exactly, exactly. Okay. Yeah, that's how quick the SQL language Yeah, yeah, yeah, just I like the syntax at this with double underscore. And you can even link to other models, if you go through underscore, underscore, and then the foreign key fields, and then underscore on this chord attributes. But of course, as we said before, we have to be careful with doing a lot of lot of queries there. But sometimes you just need to reach out to linked models, right? Yeah. Then if you want to do like more complex queries, you can use the uppercase Q, the Q objects, so you could do Q, if one field is this or Q, if another field is that. So that's a way to concatenate certain conditions, right? Because a lot of times you'll end up, you can use filter and put multiple parameters, but you're going to end up with an and which is exactly that's a good point. You don't Yes, yeah. don't always want to Yeah, like sometimes you do. But if you don't build, you're not gonna help you. That's a great addition. Because Exactly. If you do like filter, attribute equals comma, another attribute equals their end. And yeah, with you, you can do an or Yeah, if something else is convenient. Yeah. And then we have annotations. So the group by so for example, I have a tangled tip, we, we might be able to link to it. Maybe in the show notes how to get we got the most common user names on the platform, which happened to be David, Daniel and Michael.

14:31 Another other programmers names like that. Yeah, I guess so. Interesting. I feel like we almost have to create some just have your little code, say, Oh, yeah. And like link to them. Right. We could do that. I can totally do that. Yeah. And also, this one, one. I really like that how the code is laid out over multiple lines, as I guess black would do it. And you're looking at the same code, right? It's pretty elegant, I think. Yeah, it's super elegant. Yeah, I really like it. And I feel like I write Django ORM code all the time, even though I don't use Django nor do

15:00 Do I use a relational database? That's weird, right? And the reason is I use a Mongo engine, which is the ORM. ODM for MongoDB. But it's modeled on Django or M. So like, it's almost identical, you know, as much as it can be no crappy and non relational. So anyway, yeah, it's it's a really nice API. I do like, Oh, these are cool. Yeah. Well, we'll put the gist of how you got the most common usernames? Yeah. Out of first names out of your users. That's cool. And make it okay, I guess hand in glove with RMS od M's is the models that define them, right? Yeah. nice segue right

15:33 there around freeze the model. So let's talk a little bit about the muddles few tricks they're picked up. Although now add and out Oh, now, which are keyword arguments to model fields? Is this if like I have a daytime like a created date, or last updated date or something like that? Exactly. Yes. So if you have an added and edited fields, then the outro on the score. Now on the score, add would add the date upon creation. So typically, the edit and the outro on the screen now would update every time the rows updated. So that's a nice and easy way to to keep track of those dates. Like when the player Yeah, that's sweet. I love the auto Now verse. I love the distinction as well, because sometimes you want to just the default, when it's created other times like last login or last updated for a CMS page or something, that would be what you want. Yeah. And you don't have to write any code, those are just attributes that come with that field and use the use, then we have no versus blank on a field. And the distinction there is that if you say no equals true, then the field can be empty in the database, right. And if you say blank equals true, then it can be empty on the form. Right? So if you don't say blank, then and use a Django form, it might still think that the field is required in a database. So nulls for the database, I'm like is for the form that that's easy way to remember it. Okay, yeah, cool. underscore delete is an important one. Because if you link models together, and you say on Delete equals models cascade, then it will recursively when you delete a record, also delete two related records, the records in the related or linked tables, right? So for example, maybe a code challenges, there's a user, the user has done a bunch of challenges, you've saved their results, maybe some other stuff about and they logged in, if you delete the user, and you have a foreign key relationship, it's gonna, it might even freak out, right? It might say, no, this relationship is required, you can't delete the user, because there's entries in the challenge results or whatever. And this way, it'll just it'll wipe out that entire tree, like following those relationships, right? Yeah, yeah, exactly. And this deletes all their stuff, right? So and I mean, cascading deletes have always scared me, I've like almost never turned them on my asked them just like, boy, that could go a long way that could take more down with it than I actually intended. But it's very valuable and useful. And I totally get it. But it's cool. every user wants to leave the platform, right? We have to delete all their data. So I, I still live in manually. So then in Django, admin, delete user, and then it shows you like all the objects that's going to be deleted. Are you sure about that? Always look like a second time. Is that indeed the case? And, and yes, it all ties back to the user. So you don't want to delete the answer and have all kinds of ghost objects in the database potentially. So that's, it's actually useful. But if you want to keep the records, you can, instead of models cascade, you can use models set null, and then it keeps the records but where the foreign key bus user, it sets it to No. So I see a good to a kind of garbage. So the relationships not broken. Not databases, corrupted sense. But it just unwired it Yeah, yeah, it makes like there was a user link. But now it's not like it's now.

18:57 This portion of talk Python to me is brought to you by linode. Whether you're working on a personal project or managing your enterprises infrastructure, linode has the pricing support and scale that you need to take your project to the next level, with 11 data centers worldwide, including their newest data center in Sydney, Australia, enterprise grade hardware, s3 compatible storage, and the next generation network linode delivers the performance that you expect at a price that you don't get started on the node today with a $20 credit and you get access to native SSD storage a 40 gigabit network industry leading processors their revamped Cloud Manager cloud.linode.com root access to your server along with their newest API and a Python COI just visit talkpython.fm/ linode. When creating a new linode account, you'll automatically get $20 credit for your next project. Oh, and one last thing they're hiring go to lynda.com slash careers to find out more. Let them know that we sent you.

19:57 Yeah, my current systems if somebody deletes

20:00 There account, we have a deleted users table next to our users table. And then we just know out all the stuff that identifies them. But we still have the ID. So if I go back and say, this user did this thing, I can still trace back that ID and go, Oh, that's actually a user that used to exist who deleted themselves? That's interesting. Yeah, that's, that's cool. Because you do have the original data. Yeah, yeah. Yeah. Yeah. But this May this if, if you're happy to make it go away. It's really handy. Because with relational stuff, it's really hard to like I Well, I'm going to traverse all the relationships, and how do you unwind them so that the database will actually accept the Delete? Right? So this, this is really nice. Yeah. Cool. I want more model managers, right? What's up with that? Yeah, there is an example that you can define your own model or query, for example, here, I linked it to, we can we can link to it, forecast day manager, and it has a latest method. And, you know, gets the latest forecast date, or does any query really, and then you can just call that method on the object. So model dot objects, your method. So it's kind of a nice way to not have all that query logic in the view, potentially. But I have that in the model where it should be. And then it's like a property right? Where you do some a bunch of complex stuff. And then it's just click instance, dot, your property name, which is very clean. Right? So

21:29 right at once and use it in other places without thinking about it. Right. Yeah. And then again, it reads like English. Yeah. And abstract that logic in the model. Yeah. Beautiful. Yeah. And meta classes, which are not really matter class. Well, they're I guess they are, but you can define them as meta, not Python meta.

21:47 You can make a class meta and in your model, and I don't use it for many things. But for example, I think most common example is that you can define the ordering there. For example, you can say dash edit, and then in your admin, or wherever, whenever you query, that model is, then the object shall descend in descending order. Right. So the default sort if you don't specify one, yeah. Yeah, close. That's fine. Except Yeah, that's really handy. Oh, nice. Nice. All right. Now, this so far, we've been talking about besides my little diversion to Mongo engine, which not a very common use case, has been mostly Django specific. But this next one that you got here, I feel like a lot of the frameworks have an equivalent, but a lot of people probably don't use them regardless, the framework there, huh. And that's the debugging toolbar. Right. So going more into the developer toolset, yeah. Which has been very useful. It's a plugin. So you pip install it, you add it to the installed apps, I believe. And I think there's a middleware as well. So a couple of two or three settings. And then of course, you're loaded only if you are developing locally, or, which typically means is when your debug is set to true, not in production. That is super, super important. Yeah, there's tools out there that will scan websites for the presence of these debug tools and try to pull them up. It's it's bad news, to have them out there. So yeah, I mean, there's been a lot of vulnerabilities around this actually. And those are very important and easy tweaks, maybe a little segue, for example, you have like the default dash admin, slash admin. That's super easy to find, right? So it's very easy to in your URLs to make it like my dash back end, and then make it a little bit more hidden. Right? Well, yeah, exactly. I mean, I don't know how many people have like, pulled up the logs for their website, as in the request logs live and just go to the server and tell your logs or whatever, you will see untold number of requests for various PHP pages and no J's pages and whatnot. No, it has nothing to do with your site is they just like, here's the five most common back ends, you know, WP admin dot php and whatnot. Right? They're just looking for them. So surely, they're looking for Django admins as well. Yeah. So yeah, watch out with a bit of security. But the main reason I pulled up the debugging toolbar here was a story performance story, that on some pages, they became pretty slow. And I thought, okay, could be more data, more users. But actually, then when I start looking at those pages, how they load it, with the debugging toolbar, I saw that, yeah, there were actually hundreds and hundreds of queries happening. And that was imagine that would be slow. Yeah, servers on a different the database is on a different server, physical server or virtual server. Right? I've got the network latency and all that, right. Yeah. And it was actually because I was not using select on the score related to link models in an efficient way. So when you use select related, it makes one extra query to link up the two models. But then every time you access a foreign attribute, so to say, that's already there, it's like a pre cached

25:00 So once I got that in place, then the page became super fast. And But the main point was that the debugging toolbar made that super easy to to diagnose, right? Yeah. And I think probably hearing the word debugging tool bar, a lot of people who've not like, you know, like, what is this annoying thing that's on the side of my website, and I'll make this go away, right? Like, they haven't really explored it. It does catch errors. And to me, like, that's the least value, that the thing adds, the debugging part is completely, I don't know, I've other tools that tell me that you can just look at the output and the stack trace. But the real value is in the performance, you can check off things like track the performance of the actual profiling level of your code, and show me where the time has been spent. And then also into the database, right? Like, these are the queries that are happening on this page, and how many and if you see like, Oh, I'd expect two or three, and there's 500, jaigarh. This is really broken. Let's figure out why we're going and getting its second table over and over and over again. Yeah, yeah, exactly. Yeah. Yeah, yeah. So flask has an equivalent one of these pyramid has an equivalent one of these. They're awesome. You should definitely check them out. Don't deploy it in production. Yeah.

26:12 Number five, yeah, I had extending the user model. And I linked to a an article simple, from simple is better than complex, which is a great Django blog. And that's more about strategy, like when you start a project, and you're inevitably going to store more data on a user write their preference and their profile settings. And you have to kind of think like, how you, you're going to do it from the start, because Marbury or another has quite an impact on your code. So the article has four methods proxy model, the one the one with a profile table, and extra two forms of extending the abstract user base class. And especially that those last two options are really you want to do only from the start, and I believe before running the initial migrations, but I would have to look that up. For the platform, we actually went with the one to one model, the profile model, which might cause a few queries there. But it has never been really a performance issue does lead to pretty easy to maintain code. And be used the signal actually, or think they're called signals, which is interesting to highlight that when the user model gets created, you can use the receiver decorator with a post safe and then write literally three lines of code that the profile object gets created once the user object is created. So basically, when when a new user signs up through your Django app, right. And so if, if you need one table, the next you have a preferences table in a user's table, whenever you create the user, you want to automatically have the preferences created to defaults or whatever. And so you can wire it up, but basically an event that is triggered through the ORM, that when you first create one, it's going to set this up, and it's going to initialize it with one of these. Right, right. Yeah. And I think it's a nice trick to know about, like how you can signal one model to another and have the other model do something based on the other one, I think that's useful. Yeah. But I think an overall general principle that's really, I found really super valuable around like these kinds of models and database stuff is, as much as possible, use the RM to do the default thing, like the add, add now or auto now auto add auto now add that kind of stuff. Yes. Right. So when I create the object, if I don't set anything, a whole bunch of stuff will get filled out. And only the things that I have to specify, do you have to actually go right, as opposed to always updating the updated time yourself or something like that? Right. So as much as you can lean on those things? And this is like a Ross model version of that. Yeah, yeah. So usually, when you want to do something the RM has as a default way.

29:12 Yes. So again, it goes back to the previous or tip number three, like no DRM pretty well, right? Yeah, that's for sure. I don't know how you feel. But when I go around the internet, I feel like there's a lot of sites that just don't understand how their web app interacts with their database. You go there, and it takes like six seconds for the page to load. Or, you know, you go there and there's like four parts of the site that are like spinning little Ajax things for like five seconds. You're like, What is wrong with you can't be this cannot be this slow. Like, it just cannot. I don't care how many million records you have. You got to build these index and make this a little bit faster than this. Right? And just, but it's ongoing, I think, Oh, that's a good point. The database indexes super important. Yeah, yeah. And you can find another. Yeah, another attribute. You can just specify there. Yep.

30:00 I think indexes are big deal. Definitely. indexes are like magic speed dust you can throw in your database. They're beautiful. Yeah. Yeah. No, I'm not sure the ratio, but it can can be hundred times faster. Right? It's it's so easy and say 100 times faster. It's It's insane. Yeah. And it's, it's like one little anecdote like index equals true type of stuff. Right? So, so simple. But people overlook it. So, yeah, not especially in enterprise, but enterprise apps. They're always hammering on indexes. Yeah.

30:30 Imagine all right now, what's number six? class based views? Yes, it was class based views. These are basically one class corresponds to a URL, but that has different functions to respond to the different HTTP verbs like get post put that kind of stuff? Is that what these are? Are they different? Yes, that's, I would have to look up the exact classes, but you have typically like list view, detail view, which then tie into the crowd operations? Yes. Yes. Right. So you can even have one for head, which is not not that common. But sometimes, you know, if you're looking for like a browser is looking for, should I actually download this thing? Tell me the E tag, you know, last modified sort of thing. So I know whether or not my cache is still valid, stuff like that. Yeah, very cool. Okay, so yeah, and I'm kind of torn because I'm looking here at one of the, you know, the apps for the hundred days of web where we showed function based versus class based. And I like them both. Because function days, you kind of see what's happening, that you you pull all the objects, then you render a template with, give it a dictionary of things you want to render in the template. So that's it. To me, that already looks pretty pythonic and compact. But then if you compare the class based, you see all that inheritance happening. For example, we have a quote list, which inherits from ListView, which then is that magic superclass with all that default behavior, which is cool if you know him very well, but it can also be hiding a lot of stuff away. So for example, the ListView The only line there is model equals quote, which says saying, like, build me and ListView around that model, and then stuff magically happens, right. So it's cool, but it's also hiding a lot of stuff, potentially. Yeah, yeah, I hear exactly. You're saying, I feel kind of the same way, though. But it's definitely inheritance. And you can override certain methods. So if you know, Mel, it's it's it's pretty elegant and robust. Yeah. Nice. All right. Number seven. This also feels very much like the batteries included side of the Jenga story. Yeah, I call it myself pie. And I guess it's gonna be an episode in itself, right? Yeah, pretty much. I just thought that the highlight if you

32:39 guys are we just say like, meta thinks how you manage a lot. That's why it's called managed by how you manage a Django app. Important is the migrate. Of course, we all have used it. If you start a Django app, you run migrating, a ton of stuff is shown because it comes with a lot of models, the user authentication stuff embedded. But for example, you can use fake initial on migrate. And then if the database is kind of further ahead, and there's already stuff there. So it's out of sync, then fake initial is a way to kind of tell Django, well, if it's already in a database ignored, which can be useful if your database is out of sync, you have load data. For example, if you want to have a bunch of data in your initial database, or sometimes it's referred to as pictures. And you can give it a JSON file and pre populate your database, which can be useful, then we have shell, which is cool, because if you do Python, manage that py shell to drop into the Django shell, and you can play with the ORM directly. So you can do like from models, import bytes, and then it can do byte objects count byte objects, last whatever ORM stuff. So it's a nice way to it's like a repple for your web app and repple. For your, for your wrap up. Yeah, and you can play with the objects there. It's, it's pretty useful. Yeah, it's really handy. Because if you work with the ORM, you might have some of these auto, like linking auto features that set values. And if you flip over raw to the raw database, then all of a sudden you lose all that stuff that you've set up to help you kind of manage and make sure it's all consistent. All right, this way, you can kind of script around in there. Yeah, but with that safety, or whatever you call it. Yeah, exactly. Yeah. And then if you load in your production database, you can actually do that on your life database. So that's pretty useful. You want to debug something, manage that py test to run the test, but much more to say about that, then, most people that use Django will know create super user. So that gives you a bunch of prompts to create a user with all the permissions which is useful to have to quickly log into the back end. And the one I really like, lastly is the Django commands so you can write your own

35:00 Can we use it for cron jobs, for example, you can write a bit of command, which inherits from base command. And you override the handle method. And then typically what, for example, we use it to, for example, we have people on the platform doing trials. And the trials is two weeks, right? So after the two weeks, they're done with the trial. And we have to take a couple of settings on their profile to get rid of that access. And so we have a command

35:30 of queries, all the profiles profile objects, so people that have an extra trial, and then on Paris, like when they started to trial with daytime now or timezone now, and does one action already removes the access, and that's a YouTube script that's under the app management slash comments slash script. And then in a Roku, we use scheduler and then we say, Well, every day at 9am, run that script. And if you have a script and manage management slash commands, then manage that py recognizes that as as a command. So if you put a script in there, then you can use it through the Manage py interface, which is pretty cool. So you can write your own cron jobs, basically. Yeah, that makes sense. Yeah, yeah. No, that's, that's really nice. So it basically lets you just add these commands, and then tie it into the Heroku scheduler or celery or something like that, that it becomes this cool cron job that knows all about your site. Yeah, so and Roco scheduler we would define every day at 9am, run Python, managed py and the name of your command, which is the name of your script. And just like the nicer we can we have here on the notes, that template, some template code, how that would work. Maybe we can make a gist of that as well. Yeah, I think we have to make some Jess. Yeah. All right. Alright, number eight, is all about middleware, which is code that runs that might see the requests before it actually hits your interview methods or action methods, or potentially changes them after it's already been processed and decided, but before it actually goes out the web server to the end users or like a before and after the end of it, right? Yeah, that's not super common, I think. But it's a nice way to have some sort of global layer in your pipeline in the request pipeline of Django, and practical upset example. We, how we used it on the platform, was to remember when we had to make those GDPR changes, like with the regulations and stuff. Yeah, I know, we talked about this. And we all had to do weeks of rewriting stuff to make sure even though it was in the same vein, it wasn't technically the matching every rule. So we had to go and you know, go through all that and make sure there was another episode. The story is, yeah, from that one. But so we made all these changes. And we had to have some sort of form that already 10 k users or more, to have them kind of say yes to this. At one time, they had to have like another acknowledgement the next time they visited the site. Yeah. Because of where they came into, not through the login flow or whatever. Yeah, because we were they were already user. Right. So they went through a registration flow. So we couldn't put it just there. We also had to do for the existing user. So we we wrote a middleware that redirect to that kept track, if they had their consent, gave their consent on their profile. And if not, it would redirect them to that page. So that form basically birthday would give their consent. And, yeah, it was a nice way to enforce that, that login that sorry, to redirect based on a profile setting, basically. Yeah, so middleware was perfect there, because it's kind of ruthless. And

38:45 as it sits in the request, that's a really, really good point that it's ruthless. And, and in a good way, in a sense, right? Like, if you were to think, Okay, well, users need to make sure that we got to make sure they accept the GDPR at this point before they go on. So let's check where they go perform a bite where they view their solution would be where they view their account, and where they log in. And there might be some other part of the site that you forgot about, right? And, in addition to just have to modify all those places, it's super easy to forget one weird edge case, but it was middleware. Every request that hits Python, hits Django hits this thing, right. And so there's no escaping it. You've got to accept the thing, or you get a direct. Yeah, exactly. And, yeah, I also linked you to a taco article again from Theodore Freitas, right. He wrote a bunch of middleware to catch for any exception that is handling, it goes out to stack overflow. It's called the Stack Overflow exception troubleshooting. And only in debug mode, of course, would list the dumb three answers that overflow answer. Oh, that incredible. That's I saw it yesterday. I was like, This is so cool. Like it's, that's crazy. Such a cool use case. So just a wild use case. How interesting

40:00 I'm glad you're linked to that. Yeah, the two places that I use that I really actively aware of using middleware, my sites, and your pyramid has middleware as well in flask, and so on. One is for things like century where it's it's looking at for any unhandled errors, and instead of just letting the server 500 page, go back to the user, it'll catch it, report it, and then send it on, right. So it'll, it'll gather up all that information. And you basically just register that you don't have to do a lot. And the other one is, this thing, I'll just throw out a few on the bonus round really, really quick is a thing called secure pie, which will add all the headers that you should be adding for security, like do not allow my site to be embedded in an iframe on another site, right in the middle, where we'll say, I don't care how you got to this request, but we're going to tell you, you can embed this whatever this is on another site in an iframe. Oh, that's right. So yeah, it's super, super cool. And it's like literally three lines of code to do it. But because it's middleware, you know, you're not forgetting it, the whole site just now all of a sudden, as the right extra security headers. Yeah, if you're updating 20 views, then there's

41:09 a better way, right.

41:11 Exactly. Exactly. Yeah. Cool. Cool. So speaking of better ways, number nine, you should just put your API keys and your passwords right inside the code, right. But no, probably No, no. Okay. I mean, something like, committing your secret key. Just, I would just kill it. Yeah, I know, you're, yeah, it's no, that that's an important thing. There stuff that do, of course, should keep out a version control. The way to do that is to, for example, have a dot E and V file, and which you then ignore in your dot Git ignore. And then those keys are, are hidden forever, right. But you still need to reference them in your settings of pi. And there are two packages that make it pretty friendly and easy. First one is Python decouple. And you import for example, from the couple, import config, and maybe CSV depending on the setting. And then you can just do secret key equals config. And then the key right secret key, which is the actual secret key line in your dot m file. So it magically knows that there's an end file, reads it in and extracts the key from it. So really nice plugin to handle your your settings. And yeah, this is really cool. I hadn't heard of that one. That's nice. Yeah, I always recommend it to anybody using Django, really, to just pip install Python decouple and make their lives easier. Yeah. And similarly, for the database. You can use DJ database, DJ, dash database, dash URL, very similar to the couple that it uses the config method. And you can just give it a default equals config and the database URL. And yeah, so as you see here, we can put the snippet in this show notes, the databases, dictionary, config section is, is very compact. You don't have to, obviously have to have the right database URL string in your dot m file, but it's much easier. feels right, right. And database strings often contain username and passwords. hostname, so it's ports, all the stuff that you kind of not want to share. Yeah, no, no, that needs to be all hidden away. Yeah. And one tip I do have regarding the dot m file, so st dot m file is hidden from version control, it won't show up on GitHub. So I recommend to commit a dot m dot example file with the same strings with the same keys. But of course, so the same, for example, secret key allowed host and of course, not the actual data. But just as a way to communicate to other developers like this is the file we're going to use. So copy this to a dot m file and put in your SIR your credentials there. But right, it's a nice way to tie the actual database connection string here, type, the actual, an encryption key here, whatever AWS key there, right, because the platform has like 20 or 30 of those variables. And if somebody will start developing on that project, how do they know right what to set unless you run run server and just

44:21 just start screaming about tiller? Yeah, till it crashes? The thing is, though, sometimes those don't crash right away, right? Like maybe you have a MailChimp API key. And the only time that's going to scream and crash is when you actually try to register a new user not logging an existing one or you know, something like that. And then like you, you push it to production and bad things happen. And so silent error. That's the worst. Yeah, yeah, exactly. It's better stuff blows up then goes. silent. Like there's no fighting, right? no air should pass silently. Yeah, that's right. That's right. All right. Big drum roll for number 10. Even though we'll do a quick bonus round at the end as well. Yeah.

45:00 10 Yes, a big one built in template tags and filters. And yeah, there's a bunch of stuff there, I think it's just good to, as you're writing a lot of templates, where you're going to reference the objects that you pass in from the views, it's kind of handy to know how to do that. So I will just go over a few ones we learned about and use. So for example, you have a books, list of book objects, and you look through them, but sometimes there are no books, right? So instead of like doing it, books, look off the books, and else there are no books you can actually do for empty. And that's kind of a construct that Django has that if there are no objects, then it goes into the empty block. It's just shorter, right? Oh, my God, is this a proper use for like an LS block on a for? For in loop? Something like that? It might I might, actually. So you've got the the syntax, you know, you've got the angle bracket percent for book in books, Li curly curly book, right. So your that would be and then you would say n four. And that would just print out a bunch of allies with the various books that were in the list? Yeah, like you said, you're gonna want to deal with it. If it's not there. So instead of doing a whole nother test, and an else you can just say, for books, Li then percent empty. Sorry, there are no books. And for and it's all like one continuous thing. That's pretty cool. Yeah, I guess there's no shame in doing an if else performance wise, I guess. But it's just shorter code, right. It's it's more elegant. And again, it's it all goes back, like knowing about this construct. Yeah. And it's more expressive. It's like, yeah, here's the thing to put when it's empty, not Oh, I see. It means that if this thing is false, then we have nothing. But if it's true, then we can go into its book list inside. Like, it's just, it's more clear about like, here's the empty case. So it's more explicit, right? Yeah, yeah. And also, to get really nerdy, like in those templates, you get to a lot of indents. Already, because he knows like that, if you properly formatted it. So that extra FL so you can say Thursday, it's just nice, right? In two to four spaces less, it's good. The

47:12 talk Python to me is partially supported by our training courses. How does your team keep their Python skills sharp? How do you make sure new hires Get Started fast and learn the pythonic? way? If the answer is a series of boring videos that don't inspire, or a subscription service you pay way too much for and use way too little. Listen up. A Talk Python Training, we have enterprise tiers for all of our courses, get just the one course you need for your team with for reporting, and monitoring, or ditch that unused subscription for our course bundles, which include all the courses and you pay about the same price as a subscription. Once For details, visit training, talkpython.fm/ business or just email sales at talk python.fm.

47:57 demo we use a lot is overriding blocks. So in the base template, you can define a block, for example, title, title, website, and then it's again an example like class based views of inheritance, then if you go into the child template, you can just specify block title, and then give it some other contents. So you did namic. So in the base template, you can set the expectations are going to be blocks of ABC, and then in the tower template, you can then actually populate those blocks. And the thing, the advantage is that sometimes a title, for example, needs to go high up in the order of HTML. So you have to kind of the order of the elements on the page, you have to go and have it in your base template. And so it's a nice way to set it there. And then come back in a child and set it to something else. That makes sense. Yeah, I love these types of things that now have on all the sites that I run, I have three or four that are always there, obviously, the main content, right, like whatever the page contents going to be, there's going to be one for that. This title one is super important, because you want to be able to set like literally the the angle, bracket title, but there's not really a good way to get into that space. From a base template, a drive template, right, it's got to like reach in poke a hole up there. The two other that I always have are like extra CSS and extra JavaScript. So like in this page, in this few pages, I need to have one more CSS file or I need to have like this one page is going to use Vue js and be like a single page app, but not the rest of the stuff. So on this one, I'm going to like punch the vj s stuff at the end or something like that. Oh, that's cool. Yeah. For example, maybe on your checkout page, you want to have to stripe a JavaScript library, but no, no pages, right? Yeah, you can

49:36 JavaScript and then have that script in port. Darrell, though, might not be nice to have that mean, strict HTML, but, you know, I'm pretty sure like, that's probably exactly what I have it and that's a perfect use case. If something like that only appears on a few pages. You don't want to bundle the stripe. I don't even know if it makes sense in terms of their API to like minify and bundle their JavaScript with yours. It needs to

50:00 come from their site live and Yeah, exactly. But you want to stick it in the right place, not just randomly in the middle of the page. So these little like block over either just perfect, no. Oh, cool. So never hard code URLs or static files, you can

50:16 set the static at the top of your template, and then just reference static and then the relative URL, or URL to link to another page on your web app, you can just use the URL and then reference the name of the URL, I should set that in your URLs that py. Or the example here we have curly braces, percentage, and then URL keyword and then the string login. And that then matches to the login path in the URLs that py because we named it write that explicitly. That's a good thing to know, don't go hard code URLs, because he switched domain or whatever. And that will break right? Yeah, yeah, typical. Other thing I like is filters. So I have a text of pot tags.py file, and you have a bunch of registered filter decorators. So for example, here, we wrote one that's is new with that receives a daytime and that looks if that daytime is less than seven days in the past. So if something is a week old, so and then we use it in the templates, for example, we have bi dot edit, and that's again that edit fields that was without a now and then we can do pipe is new, goes a bit into the weeds, but basically, applying that his new filter on a date in the template you can kind of play with it. And Bobby do for example is to give it a class. And then I guess show a new image on it. That bit a little new badge or something on it. Yeah. Yeah, I guess if we post the snippet that makes more sense. But yeah, basically, it's a way to, to write a filter. And that you don't have to do a lot of if else and complex logic in the template. But you have that actually in the back end. And then you can just use it as on the object in the template, I guess. Yeah. Let's show the the code images. Yeah, that's good. But yeah, it's a cool way to basically put a little pipe filtering operator on there, and it runs a little bit of custom code that you write Yeah, in. You write it in Python, it runs it in templates. Yeah, exactly. Yeah. That's what I stated, I think. Yeah, yeah. And you can do anything, right. So it's a pretty robust. So when I'm looking through this, you're talking about templates a lot. A little while ago, we talked about how it was nice to start out with some code. Or when you're creating these pages, maybe the database is empty, but you want some stuff in the page, because it's super hard to actually see what's going on, and design the pages without some content. So maybe some kind of lorem ipsum. No, that's fine. That that comes out of the box, right? I was so surprised that Django has lorem ipsum built in to it must be in high demand, you know? Exactly. Now, it would be better. I mean, this is pretty good. It would be better if it were hipster ipsum which is like lorem ipsum. But speaks

53:13 it speaks hipsters speak I guess you would call it like Stumptown Expo Expo kitara, semiotics PBR and NP street art Blue Bottle before they sold out a pop up mixtape, and, of course, Portland shows up in here.

53:30 Yeah, so anyway, if people are looking for like lorem ipsum filler, there's actually like a lorem ipsum operation like empty as well. Jayco Wow. That's really cool. Yeah, let me see. I pull it really quick to see the tag. It is how you just do percent loram count method. randomness, close percent close curly. Boom outcomes. It's beautiful. Yeah. Lauren to W random. Well, I'll put two random Latin words How cool is that? Yeah, so that's really cool, actually, that it's built right into the templates. And what's nice is you don't have to have like paragraphs of junk that you're going to then delete you have literally like just a little bit with like, I want 20 words here. Right so Super Bowl. Remember when you were maybe it was recoding one time like a pretty print of how much time a comment was posted like four days and six hours ago. So I actually thought that was human eyes and I guess human eyes can do that. But it's actually here on the tax page. time since Yeah. Oh really? Like it takes a day time and then it will like humanize it into hours half an hour ago an hour ago we could go down to Oh, that is super cool. Yeah, I love to see dates like that. Yeah, use that on our on our messages and forums. It's super nice that this is Riyadh perfect, nicer, you know, and don't have to write that logic. Right. You just comes in a template. Perfect. We're spoiled batteries. Alright, so are you ready for a bonus round? Yeah. Yeah, that's right. So bonus round. Let's do it. Now.

55:00 So a bonus in one hit. Okay. And I've not used this that much, but playing with it yesterday, it's actually pretty cool. So Django extensions, and I will just highlight a few things you can do. You can do Python manage the PI graph models, and then

55:17 minus a minus o and then a PNG, and it will make a PNG or ping, whatever you call off all your models in your, like a UML diagram of your Django or M models, basically. Yeah, something like that. And how they're linked together. Yeah, minus normally UML. But yeah, it's definitely more or less. Yeah, it's it's so small, because there's so many models, in our thing, but a wrinkle exactly like how you can visualize that, I guess, if you would, you know, get more developers on board. Yeah, you talked about shell. Yeah, I mentioned shell before. And there's actually a shell on the score plus, that comes with the Django extensions. And then you can also give a dash as ipython. And then you drop into an ipython shell. And it also imports all your models, so you don't have to import them manually. So it's pretty convenient. And not part of the Django extension. But I did want to mention is a plugin called Django dash tiny MC E, which gives you a rich text editing field. And it's

56:23 so tiny MC is like a wiziwig. What you see what you get HTML editor, right? Yes. Yeah. So this like brings it in or something like makes it easy to use in Django? Yeah. So you would use the HTML field. So from tiny MC dot models import HTML field, so it would, of course, cause another migration. But yeah, it's it's pretty easy to use. And it's a huge improvement for the end user. Right? So yeah, that's super cool. You know why you're on the topic of that. I'll throw one more out. There is simple mbe.com. Huh. So tiny MC is cool. But I think the ultimate outcome is HTML. and simple. MBE is a beautiful markdown editor that's just pure Java, pure client side JavaScript. It has like hotkeys. It has side by side secret I scrolling. All like even the markdown, like the text in markdown, even though it's plain text is like the headings are bigger than the code bits and whatnot. It's really easy. Just throw it on a text area book. super nice. Yeah, yeah. It's very nice. To turn off spell checker, it'll tell you everything's misspelled.

57:28 All right, I bonus number two, even flying salary. Yeah, salary really want to mention that? Because we're, especially in the enterprise where I see Django. I see salary notes, there's always tasks that are that have to be offloaded, and be done. async wise, it makes sense. Right? Right. Some things are just not meant to be done in the context of a direct request. I learned this the hard way with my site. So there's a back end that will let me email the people in a particular course, like so I could go there's an update, like a problem with the course I go into that course that email, everybody subscribed here.

58:05 The first time I did, I didn't really think this all the way through. I went in and I filled out an email, hit go. It just sat there. And it's fun. And it's fun. And it's fun. And then eventually it timed out after like 20 seconds and crashed. And I go No. So it emailed like thousands of people, but I don't know who actually got the email, everybody. And it got partway through and then crashed. And so then what I do I email them again, the first half will get the double the second half didn't get it at all. I just like what have I done? What a fool? Yeah, so don't do that. That's a bad experience. Now your Sunday evening will be shorter, right? Because you know, that RM and you can, but yeah, you would have to write some sort of script to see who got emailed or not, you know? Yeah, exactly. I go, like, scrape the logs or something. Right, like, exactly, yeah, I paid for an essay. Well, I guess the other half of the class is just not getting that message. I'm sorry. Yeah. So now it's salary. Right, you would click sent and you would be immediately back at the from the request cycle. So back at your interface, right, dump it in a queue, throw it at salary and say, start emailing these people. It's on the queue. And it's all happening in the background. Yeah, so that's,

59:10 and you know, for fraud or things like heavy file processing, anything intensive, send it to you, right, because the user should be waiting for that. I think even for some of my stuff, I started doing logging on a queue. I'm just like, I don't want this, whatever this is, I don't want it to like be part of this request. I'm just gonna throw it over there. And we'll get to it in a minute. You know what I mean? Yeah, yeah, yeah. And a quick debugging tip. If you want to debug celery, actually, sometimes it's convenient to not send it to a queue and have it as part of your main process. And you can set salary underscore, always underscore eager equals true in your settings. And then although then it doesn't go to a test queue anymore, but it goes straight to your main console where you have run server running, and it's just easier to debug. So just want to mention a tip that that

01:00:00 Not very well documented, but definitely helped me a few. Okay, yeah, very cool. That's awesome. I definitely need to make better use of celery and what I'm doing as well. All right, last one, this one I just threw on there. So I'll tell you about a Bob, I told you that there's like all these headers you should be putting into your code into your HTTP response. And if you go look at the OWASP, top 10, web vulnerabilities, the open web security group, or whatever that was stands for, they go through, they keep track of all the problems, right. And some of those can be, you know, cross site scripting, embedding your stuff, and something that looks like your site like embed something that basically is your site in an iframe, but then put a transparent overlay that captures keystrokes for like, say username and password, all sorts of bad stuff like that. So there's all these headers you should send back to if use this thing called secure pi, which is github.com, type slash type error slash secure.pi. And I don't know how they got this, but it's pip install secure, which is incredible. That's still available. But the idea is it just on any of these frameworks, including Django, it will just as middleware, just drop in all the changes you need. And it's like, for Django, let's see, what does it take? Oh, that's just hang up. There's a super simple integration on how to set it up. How to pull the docs anyway, it's really super easy. And then you get things like strict transport, security, cross site protection, extreme options, the same origin, like all those kinds of things that you would like to have, that you might forget. And because it's middlewares, just like magic. Wow, that's really cool. Yeah. And that's why it works with like, 15 different frameworks or 10 different frameworks. It's really, almost no matter what you're using, it works with it, you know, yeah. Wow, I just started to middleware app dot secure middleware dot set secure headers. Yeah. Pretty cool. Yeah. It's literally like one function, like a simple decorator that you write more or less simple, simple middleware. Yeah, just add it in there. And off it goes. So it integrates, just like you'd expect. Anyway, that's just, it's so easy to add that security. And who knows, if something else comes out that you're supposed to start doing, you know, secure.pi might get updated, and your site will just magically be more secure. And you don't have to think about that, which is always nice. Yeah, theoretically. Pretty cool. Thanks. Yeah. Yeah, you bet. Of course, of course. All right. Well,

01:02:17 we did it. We didn't take four hours to cover that even though I did take some time. I mean, we you guys who are listening to can't see there's a ton of details we kind of skipped over because we got it. Right. Like, like you said with manage that py is probably its whole episode. For example. We've got Django test, but Django rest framework. We got wagtail. We got century thingo channels. We haven't even touched on authentication. There's all sorts of stuff, right that you didn't mention century. You didn't mention? I did but yeah. Facial item. Yeah, century school, because there are some 500 errors we would have never known about. Well, yeah, exactly. or anything. Oh, it's so rare. They're so rare. And they're under weird edge cases. And if you run a website, you should definitely install something like Fintry, or robar, or something like that, where you get notifications. Anytime there's an error. At first, it's annoying. Like there's certain things that you can't control, somebody will try to, you know, post a binary thing to some part of your API, where expects like Latin characters, you'll get like a non Latin pars area, like okay, well, there's nothing I could do about this. But you could start muting those types of things. And eventually, you'll be like, Oh, I got these errors. And literally, I would say, more debt. Certainly more than one time, I have seen an error come in over one of those channels, figured out what was going on, fixed it and sent a message to the user and said, I'm sorry, I had this error. Here's I fixed it. And they're like, Well, I was just about to write you. This is crazy that you actually, I didn't even tell you there was an error. And you fixed it in contacted me. That's right. Yeah. is often a 500 error. This sucks. And they go away. Right?

01:03:59 Exactly. And now you're proactive about it. So that really makes a difference. Yeah. And even if they're mad, and they go away, and they've lost faith, whatever. Like, you know, there's nothing you can do to change the past. But it's your site is better every time you catch one of these errors that you wouldn't have caught. So yeah, but I read a read a lot of time. It's like edge cases. But sometimes there's something that might indicate a bigger problem. So it's good to write, or you deploy something that's bad. And all of a sudden, it's like gone crazy in your email and text messages are fully like, Whoa, whoa, whoa, I better go check this out. Isn't that good? Yeah, it feels a bit safer, right to do a git push to having that. It's a better system. Yeah. Yeah. At least you'll see the smoke if it catches on fire.

01:04:41 All right. Well, these are really fun things to cover, Bob. I think people really enjoy them. We can put together some of them just and we'll try to link to the others in the show notes. Yeah, cool. We will do Yeah, but you don't get out of here without answering the final two questions. Oh, so if you're gonna write some Django code, what editor to use? Yes, I still use him.

01:05:01 They'll go away.

01:05:03 Yeah, it's I always say it's a steep learning curve, right? The beginning was very awkward using that editor, but it has this compound effect. And when once you get to a lot of shortcuts, and you just become pretty fast in it, and it's very convenient, but I'm missing out on all the ID features, I guess. Yeah, yeah. That's cool. You want to hear a little them joke? Yeah. Yeah, I might. Yeah. So how do you generate a random string? Yeah, I know.

01:05:34 You put a first year computer science students in a VM.

01:05:40 So good.

01:05:42 Yeah, it's all good. All right. And then we covered so many packages here, but maybe just throw out a couple of packages that you're like, man, people need to know about this thing. Yeah, I'm going to

01:05:52 kind of use the fact that we had to leave some out to put them in here. So we didn't talk about

01:05:59 this round, the bonus bonus. So Django all out is a great package or plug into. You have to really make your authentication in Django easy. And and Django rest framework. I still find that a great, great package chaufeur to build API's in Django. But if it doesn't have to be Django, then let's throw in Python date. util, which is really cool. Yeah. Yeah. Python data feels awesome. I love its ability to parse stuff without me think too much about fuzzy fuzzy parsing, right? Yes, exactly. The parser. Always works. It is so nice. Because you don't have to remember strp time to just throw it into parse and it magically converted to daytime object, right? Yeah. Yeah, absolutely. There's some site and I can't remember what it is, I know covered on Python bytes. But unfortunately, I'm not tracking it down. Right now. There's a site that will let you type in a human readable string and then tell you the format string that goes with it. So nice. Oh, no, that's cool. Yeah. So you type like Wednesday at two 2pm. And it'll it'll actually pull it up. I can't find it that well, anyway. Yeah. Let's go long story short. This is a great package. If you're parsing things Python dash dot util. Yeah. And I can I mentioned before, though, if you're working with databases, which obviously haven't, so when you when you do web development in Django, for Postgres, PGC Li bccla is like way nicer interface, then P SQL. Yeah. So just pip install it. And you will have a lot more fun working with Postgres databases from the command line. Nice. Do you know one I know when that you recommended was SQL lite browser at SQL lite browser.org. Which is pretty cool. But that's just for SQL Lite. Have you come across beekeeper studio at beekeeper? studio.io? No. Oh, my goodness. So this is a free open source database GUI for Postgres SQL lite SQL Server, presumably, also, Oracle works on all the platforms. And man, it is cool. You can even have like saved queries you typically run it has autocomplete all kinds of stuff. Wow, it looks pretty nice. And it looks good. Right? I guess. It looks like you'd want to use. Yeah, like, even just an autocomplete query. thing. Composer is pretty cool. So anyway, I need to link to that as well. Yeah, we're gonna throw out to database management stuff. That's a really good one. I should definitely put that in there as well. Cool. All right. Well, we covered a lot of stuff, what a whirlwind. But it was really fun. So yeah, I guess the final call to action, and people are all excited about what you're talking about. Also, maybe they're interested to see how you've taken some of these ideas and put them into action over a coach challenges, you know, final action and what what should people do? Yeah, so we don't have bite exercises on Django. That was a bit hard. But regardless, yeah, it's hard to set up the whole server and database infrastructure in like a little tiny bit. Right? It might be possible. So So I think we have to have a flask bite. So I think it's possible because we can install any packages on our AWS lambdas. Right, right. Regardless, go to code challenge dot Yes. And go write some code. That's the best thing you can do. You want to learn Python. And you can also reach out to me by our slack. So if you go to pi bi DS, or on the resources, there's a community link, anybody join your slack there? Yeah, that's totally for the community. You've got a really, really vibrant and self sustaining Slack channel for Python developers like more than most other places I've seen, which is really cool. I know you've got thousands of people in there, right? Yeah, I think we crossed the 2000 mark. And yeah, it's awesome. How people are interacting responding helping each other. It's, it's, it's such a nice place. Yeah, go there. Go to code challenge dot s slash community. Is that it? No, there is a slack bot logo on the platform. But if you just want the link, then you can also just go to pi bite. Yes. And under the resources drop down, there's a community link.

01:10:00 Right, because like sometimes the invite link, yeah, don't get me started expires or whatever. Don't get me started on getting joined into slack man. So we just have a dedicated page. And if you go to pi bi pilot dot yes then that always works.

01:10:16 Awesome. All right. Well, thank you were taking the time to come on here and talk all about this and congratulations on going full time on your project. Awesome. Good work. Thank you. Thanks for having me. I'm so grateful. Yeah, you bet as always see? All right. Yes, bye. This has been another episode of talk Python. To me. Our guest in this episode was Bob builder boss, and it's been brought to you by linode. And us over at Talk Python Training. Start your next Python project on the nodes state of the art cloud service. Just visit talkpython.fm/ linode li n o d, you'll automatically get a $20 credit when you create a new account. Want to level up your Python. If you're just getting started, try my Python jumpstart by building 10 apps course. Or if you're looking for something more advanced, check out our new async course the digs into all the different types of async programming you can do in Python. And of course, if you're interested in more than one of these, be sure to check out our everything bundle. It's like a subscription that never expires. Be sure to subscribe to the show. Open your favorite pod catcher and search for Python. We should be right at the top. You can also find the iTunes feed at /itunes. The Google Play feed is /play in the direct RSS feed at /rss on talk python.fm. This is your host Michael Kennedy. Thanks so much for listening. I really appreciate it. Don't get out there and write some Python code

Back to show page
Talk Python's Mastodon Michael Kennedy's Mastodon