Come on in, the Water’s Fine: Making Python More Approachable
Published November 3, 2022
This video features Melanie Arbor at DjangoCon US 2017 in Spokane, Washington, USA.
DjangoCon US 2017 - Stumbling Through Django and How Not To by Melanie Crutchfield
If you’re a beginner about to embark on a new Django project adventure, this talk is for you.
When I started my first Django project, I took the “Sure, I think I can figure that out” approach, which is fun! And also dangerous. But exciting! And also horrible because I caused myself a lot of trouble and barfed on my keyboard. (Metaphorically.) Oops.
My hope for this talk is to pass along lessons I learned the hard way, and save the world. Or at least prevent some frustration. :) We’ll talk about version control, structuring your project, and how to handle top secret stuff. We’ll also talk about throwing house parties without causing anaphylaxis, pregnant daddy seahorses, velociraptors, and friends. I promise all of that is related to Django.
This talk was presented at: https://2017.djangocon.us/talks/stumbling-through-django-and-how-not-to/
LINKS:
Follow Melanie Crutchfield 👇
On Twitter: https://twitter.com/hellomelaniec
Official homepage: http://www.melaniecrutchfield.com
Follow DjangCon US 👇
https://twitter.com/djangocon
Follow DEFNA 👇
https://twitter.com/defnado
https://www.defna.org/
Melanie Crutchfield recounts the avoidable mistakes she made while learning Django and turns each into practical advice. She explains why virtual environments isolate projects and dependencies, how separate Django apps keep functionality manageable, why local copies of static assets can make development work offline, and how Git branches provide a safe way to experiment. She also warns against committing secret keys and credentials, recommending environment variables, and argues that supportive communities make it easier to learn, recover from mistakes, and eventually help newer developers.
Summarised automatically from the transcript.
Automatically transcribed, so expect mistakes in names and technical terms.
Hi. You all look so nervous. You can calm down. Everything's gonna be fine. I don't know why you're so worried. My name is Melanie. I'm a new-ish Django developer. You know that saying that somebody knows just enough to cause trouble? Like that's who I am. So you may be asking yourself, why am I listening to this person who is not super fancy pants? I don't know how you make your choices, friend. It's quite possible that you're lost and looking for a donut. But if you're here for Django or for donuts, I know what I want you to get out of this talk.
Okay, here it is. Not too long ago, I was diving face and brains first into my very first Django project. Um there was a lot of chaos and confusion um and carrots. There weren't any carrots, but I really like alliteration. But it was just kind of swirls of expletives and face palm and general madness, I made some big costly mistakes, and it turns out that those are decently avoidable. So that's what I aim to give you. I want to lay out the beat-by-beat post-mortem of all of my flailing missteps so that you may avoid crying on your keyboards and vomiting on your
rubber ducks. Not that I did that, but but you might. I don't know you. Here we go. Throwing house parties without causing anaphylaxis with Django. So It's totally normal, don't laugh. Um the recommendation to me was to create virtual environments, um, which I dismissed immediately because if I believe in anything, I believe in laziness um and climate change. because of science. And that the toilet paper goes over and not under because I'm like a decent person, right? Yeah. Um I also didn't totally understand what a virtual environment was or what it was going to do for me, and I certainly wasn't going to unlazy
myself for no good reason. So let's take a look at that really quick quick. Quick note, this is a rather long analogy. So just pretend that you all love long analogies, especially the ones with bad drawings. Thank you very much. much here we go okay so let's say that you have built a big and beautiful house and you've made it with a massive living room The living room is actually, I can tell you love this drawing. I can feel it from your heart. That's awesome. Okay, um the living room is so big that you haven't bothered to make other rooms. You're just like, I have a sweet living room, whatever. So now you have some friends that want you to host a party at your house and you're like, have you seen my living room? It's amazing. Of course I can do that. And so you tell them
okay Your friends tell you what they need for the party. They need classical piano music, they need ham sandwiches, obviously, and very critically they need there to be no peanuts. because every last one of them is terribly allergic. You can do this. Everything's fine. So here comes a second group of friends and they also want to have a party in your massive living room and you're like, I can totally do that. And they're like, we need classical strings music. Okay, that's fine. They need turkey legs. All so fine. And they need bottle rockets because they're weirdos, apparently. Whatever. You still say sure. Everything works fine. Another group comes, you know, well, oh wait, we're not there yet.
We're saying that it's fine. Everything went well. We're just gonna skip over how well it went. It was awesome. Everyone wept with joy The next group comes. They're like, we totally want to party. And you're like, obviously I'm amazing at it. There's already two here and everyone's having a good time. and they've had this party in other places before and they bring all their own stuff and you're like sweet you just let them do their thing right? However, it turns out that while you weren't looking, they took a whole host of peanuts and threw them everywhere, and now your first Group is dead. So bad. Look at how sad they are. If they have X's for I's, y'all. How this relates to Django. Um Thank you for bearing through that.
The first group is your first project, right? It's hanging out, it's having a good time. You put it in a second project, also fine. Like it's a little bit different, right? But not so different that they can't get along. Um The third project though, maybe it has a different version of Python and a different version of Django. And once you install the requirements file, your first project just blows up Bummer. And this brings us back to virtual environments. The logical solution for throwing parties without becoming a mass murder murderer via peanuts. is to build rooms, right? You build the rooms, you stick each party in a different room, and no one kills each other. Hooray! That's like optimal for throwing parties, just in case.
Virtual environments do the same thing for development. You can look this up in the documentation, but here's the quick basics on it. In Python 2, there is a package called virtualenv that we install with pip install virtualenv. And then whenever we want to build a room, build an environment, we say virtual env and the name of the environment. Obviously in this case peanut-free because of the murdering. In Python 3, this is built-in. So we don't have to install anything extra. We just type Python 3 -M V-E-N. be full of peanuts and it will make that virtual environment for us. You need to activate the environment, otherwise it's just like going back to the living room and it'll just grab whatever you have installed on your system.
And so to do that, we'll type source, the name of your project, slash bin, slash activate. And when we press enter, it shows us that we've activated the environment by putting the name of the environment in parentheses at the beginning of the project. Now, there's one more tool that although it involves installing a different thing which interferes with my laziness, it actually enables additional laziness later. So I've started using it exactly. So it's called virtual env wrapper , and we install it with pip install virtual envrapper, just like we did before Then, oh my gosh, we have to take a second step by adding something to our bash profile.
You can look this up also in the documentation for Virtual and Vapper later, but this is what it looks like Oh my gosh, it's so much. It's two lines. But all of this allows us to do this later. We just type mk virtual env and the name of the environment. to make a virtual environment. And it automatically, when you make it, activates it for you as well. So you don't have to do the whole like source, la la la, whatever that stuff was that I said. Later, when we want to work on it, we just type work on and the name of the environment and it activates it for us. Did you forget the name of your environment? Of course you did.
You're a human person. Just type work on, press enter, and it tells you all of your environments. Oh my gosh, they're all there. Don't you love it? Yes. Okay, next. Saying no to sea monsters and yes to pregnant daddy seahorses with Django When I started my first Django project, what I understood myself to be doing was building a web app, right? It's an app, there's one, you're building, here we go, got it. So when you're looking at the commands that we use to create a Django web app, we use start project and then we use start app, which is obviously Still kind of your web app, I think, pretty much.
So in my mind, we started a project. Um we started one app, because we're only making one app, right? Something like this. Um and then we would just shove everything into that app and it would be awesome. Why would you make more than one app? Well, there are lots of things that we typically need to do with a project. In FiveUp, my tiny baby project, I have to store a collection of images that I curate. I have to store messages that users enter and I have to schedule and send messages. Providing this functionality requires a bunch of of models and views and other fun stuff. If I try to start one and only one app this starts to look a little monstrous.
You have one file for your models, you have one file for your views, and everything just gets like bigger and bigger. So now when you go back to find code for a specific thing that you want to adjust, it's just kind of like a miserable task that looks like that. and makes you dream of scary things. So we use apps to avoid this. But we don't want to just be like, this is messy and long, so I'm gonna make a new app and then just it's like whatever. What you want to do is think about each thing that your project needs to do and make a separate app for that. So with FiveUp I started out with everything all jumbled into one app called FiveUp creatively. But I eventually transitioned to have an app for curated messages, an app for custom user messages, and an app for sending messages.
as well as this authentication thing that I made that's a little like and I accidentally named it um F U Auth We're five up, right? Dang it. Um so what we've done is instead of taking our baby seahorses and gluing them on the dad's like head and neck and back and feet. Seahorses don't have feet, they have tails, gluing it on their tails. We've left them as their own little adorable things and put them in the protection of the daddy seahorse. Okay, side note on this.
I decided on this analogy before I had Googled what a Daddy Seahorse looks like, and oh my god, it is terrifying. Like, it's the stuff of nightmares. Don't do that Protecting your velociraptors with Django. So in my voyage through my first Django project, I came across this blog post. Sorry, friend that wrote the blog post item. I don't know what your name is, so you don't get credit. Haha, just kidding. Um, whatever. Anyway. The blog post told me to save all of my static files locally So this means that when I was using Bootstrap, in addition to linking to the CDN, I would download all of the CSS files and all the JavaScript and save them in my static folder.
Recalling that I am excessively lazy, this did not sound like something I wanted to do. Surely that was at least two more steps. No, thank you. Um and why? Why would you do this? Allow me to illustrate my design. Let's say that I found this really amazing gQuery thing that does something awesome. Something possibly like this. That's amazing. Um and we also know that there's like a ton of really useful reasons to put a velociraptor on your website. Don't even pretend like there isn't. Anyway, my thing was like a modal, which is way boring and doesn't have any dinosaurs in it. But anyway, so we'll just pretend that I did the dinosaur thing because it's better. Anyway. So I do this amazing thing, right? I go to coffee shop to continue working on my amazing things.
And uh I don't know the Wi-Fi password. And like the barista looks really busy and I didn't want to bother them. So I thought to myself, hey, I'm working in a local environment. I totally don't need the internet. Internet doesn't own me. Internet totally owns you. Anyway, um I started up my local server and I go to the old like 127 blah blah blah whatever it is only to discover that my velociraptor is gone and everything looks like 1992 which was not an amazing year. Surely I have done something horrible, right? Because I'm a beginner and I've done numerous horrible things. at this point. So I just start ripping apart my code. That's logical, right? I just am like digging through everything and changing random things and like, I don't know, I screwed something up.
Let's ruin everything. There was a lot of ripping apart. So eventually I decide that I need to Google this, right? Because that's what you do. So I go and like bag the Brewsta for the Wi-Fi password. And I go like I look up like one thing and then go and refresh my server and my beautiful Velociraptor greets me again. Tears of joy. Um, and that's when it clicks. That the only thing that was happening was that because of my lack of internet, I couldn't access like my CSS files, JavaScript files, anything that mattered files. And that's what happened. All of my independence from the internet was a lie. If I had saved those files locally, I wouldn't have had that problem, right?
So there you go. Which brings me neatly to my next topic. Terrified abandonment of dreadful mistakes in Django. All of this was happening on the one and only copy of my code, my master branch. Um remember that lady? Yes. She was like, I'm gonna restore that nineteenth century fresco of Jesus. It's not that my project is like an amazing piece of art, but like maybe we both should have made a copy first. And um we recall how much ripping apart I did. It was quite a bit
And while my renewed internet access solved my velociraptor problems, um That's the last time I promised that it's just so cute. Uh anyway, it didn't solve all of the new problems that I had created because I had gone so far down the rabbit hole of fixing non-existent problems I had no idea how to get back to where I started. This is not great. I honestly don't know how I got back to where I was. I just kind of like, hmm, and then eventually it worked out because that's basically what coding looks like, right? I mean I don't know. Like I said, I'm not experienced. I assumed everyone does this. Anyway, you don't have to tell me about that. Since that time, I've discovered what I can essentially use as Git
's version of a panic button. It's Git branching. It's amazing. So instead of using my anxious confusion to destroy all of my work, I could have done this. Git checkout B to create a new branch appropriately called oh my god what have I done and then I could commit these changes to this new trash branch with an appropriate git commit message made a giant mess of things. And then I could check out the master branch and pretend that none of it ever happened. Which is what I do with all of my mistakes. Um hooray! So at this point I've gotten in the habit most of the time of just creating the branch first
before I get myself into trouble. So now my workflow looks like this. Say I want to remove the Velociraptor because I promised you all I wouldn't do it anymore. Sad thing. I don't know why you don't like velociraptors. Anyway, so I would make my changes. And once I've confirmed that the changes are good, then I would uh Commit it and then check out the master branch and merge the changes. You may need a different workflow based on the team that you're working with or other things, I don't know. Um but the point is if you're going to make changes make a new branch first Unless you love drama, then do what you want. Like I'm not the boss of you.
Okay. Last two. Being suave and mysterious with Django. Surely I couldn't have destroyed more than this, right? I mean this is quite a bit at this point. It's getting ridiculous. So wrong, friends. It's very wrong. Um and this one actually feels like really tricky, like I've been tricked or something. Like I know that's not the case, but like it super feels like that. Um and it was actually exacerbated a little bit by the fact that I'm using Git responsibly somewhat. So what could it be? Let's find out. It's a mystery. Okay. So this is my settings file, right? This is the settings file that happens when you start a project in Jenga. And notice this lovely warning. Security warning. Keep the secret key used in production secret. It doesn't explicitly tell us how to do that though.
So When the time came to deploy, I thought, well, that's a cute idea that I don't know how to do. Ta-da, let's just push it up. And so that's what I did. Yeah, I know. As it turns out, this project also needed my email address. email password and for good yeah I know um for good measure I went ahead and put in some API keys and like a portion of my seventh grade diary and um why not Uh yeah. So please do not shame me publicly, right? I I mean I think that's actually what I'm doing right now because this is gonna go on the internet. But anyway, I guess just enjoy my shame and hopefully
it will save you. some trouble in the future. You don't ever do this, right? So I'm going to, if this was something that you were going to do, I will tell you how not to. It's just one way to do it. There's lots of different ways. So but this is what I do. Remember when we were talking about virtual environments? Aside from keeping people from dying of peanut allergies, metaphorically, they can also hold our deepest darkest secrets. That way our secrets aren't going to get into production and they're not going to get into your Git history like my did. So We're going to go to our activate script. For me, since I'm using virtual inBrapper, all of my virtual environments are in an IMS folder. And so we'll go to MS.
Extra peanuts, then activate, and we'll open up that activate script and add this bit to the end. This is going to set a variable and export it with your actual secret key. Okay. Now in our settings file we'll add this function. I believe this is what's recommended in two scoops of Django. So if you don't have a photographic memory you can look look it up there. Then in our settings file, instead of having the actual secret key, will put this function. And uh what it will do is that it finds uh our environment variable that we set in the activate script and you're all set. So it's
super fancy and mysterious. When you deploy, you'll set whatever environment variable you set in your activate script there as well. In Heroku they're called config variables, but they could have different names. depending on where you deploy, find that place, set your variable, and you're all set. That way if you're working locally or if you're deployed, it will find the variables that it needs and there'll be a Done. Making friends with Django. Okay, last thing. None of this would have been even ready Remotely possible without the San Diego Python user group, San Diego Pi Ladies, and of course our Blessed Mother, the Internet. But
the most important by far of the three is San Diego Python User Group and PyLadies. This is where I've gone nearly every Saturday for the past three years for encouragement. for help, for camaraderie. Our Saturday study groups are what made me believe I could do any of this to begin with. And I've found a place where it's okay to be at whatever level of your learning that that you're at. Our study group is absolutely why I'm here. I can't stress how wonderful and important our community is. is. And I want to show you something really quick that I worked on for literally hours, like six hours. I couldn't figure out why I could submit a form,
but it wouldn't actually save a record to my database. Um, and I worked on it like crazy and then 60 seconds at our study group brought me this. It's one character for every hour I spent. That makes me feel good about myself. Um, special thanks to Micah for helping me on that one, even though you laughed at me me a lot during the process. And the amazing thing is that a couple years later I was able to do a similar teeny weeny fix for a perplexing problem for a new developer. This is why we need community. I'm still learning. I hope I never give up the title of learner because I find that it allows me to be kind and generous with myself.
And I think the most costly mistake we can make is to stop expecting mistakes and start demanding for perfection from our silly flawed themselves. In the words of Brene Brown, there is no innovation and creativity without failure, period. So in conclusion, I wish you tidy development environments, adorable Django project structures. Internet connection proof velociraptors, easy get escape routes, mysterious secret keys and passwords Super smart friends and lots and lots of mistakes. Just hopefully not these exact ones.
That's the end. Thank you.
Virtual environments isolate each project’s Python and Django dependencies, preventing one project’s versions or packages from breaking another. Without activating the environment, commands use whatever is installed globally.
Discussed at 4:57For Python 2, install `virtualenv` and create an environment with `virtualenv NAME`; Python 3 includes this through `python3 -m venv NAME`. Activate it with `source NAME/bin/activate`, or use virtualenvwrapper’s `mkvirtualenv` and `workon` commands.
Discussed at 5:46Create separate apps around the distinct things the project needs to do, such as curated messages, user messages, and message sending. This keeps models, views, and related code from becoming one large, unmanageable app.
Discussed at 9:39If Bootstrap or other CSS and JavaScript are loaded only from a CDN, the local site can lose its styling and functionality without an internet connection. Keeping the files locally makes development work offline.
Discussed at 13:39Create a new branch before experimenting, make and commit the changes there, and return to the master branch if they cause problems. Once the changes are verified, merge the branch back into the main branch.
Discussed at 16:01Store secrets in environment variables rather than directly in `settings.py` or committed source code. Set the variables in the virtual environment locally and configure equivalent environment or config variables on the deployment platform, such as Heroku.
Discussed at 19:06User groups and study communities can provide encouragement, troubleshooting help, and camaraderie at any skill level. The speaker credits the San Diego Python User Group and PyLadies with helping her learn Django and solve problems quickly.
Discussed at 21:24Note: We understand that names change, people change, and bodies change. We respect each individual's journey and privacy. If you have any concerns about a video or need us to remove content, please don't hesitate to contact us. We will handle your request with care and promptly address any issues.
Published July 15, 2026
Published July 15, 2026
Published July 15, 2026
Published July 15, 2026
Published July 15, 2026
Published July 14, 2026