Upgrading Django (to 1.7)

This video features Andrew Pinkham at DjangoCon US 2014 in Portland, Oregon, USA.

Upgrading Django (to 1.7)
0:45:17
Published September 17, 2014
1,492 views

By, Andrew Pinkham
Want to learn about Django 1.7 and how to upgrade Django? Are you unclear on what the numbers 1.7 mean or how Django rolls out new versions? Find upgrading daunting? Want to better keep up with changes being made in Django? This talk is for you.

Help us caption & translate this video!

http://amara.org/v/FOP4/

Summary

Andrew Pinkham explains how Django’s major, minor, and micro version numbers work, including release candidates, supported versions, deprecation over two releases, and the importance of running the latest patch release. He reviews the upgrade-relevant changes from Django 1.4 through 1.7, especially Python 2.7 being required, Python 2.6 being dropped, and the new system checks. The practical comparison of Django 1.6 with 1.7 focuses on native migrations: model changes are recorded and applied through migration files, data changes should use data migrations rather than the deprecated initial-data mechanism, and historical models must be accessed through the migration app registry. He also explains that South is replaced by Django’s built-in migrations in 1.7, and briefly introduces the new app registry and other ORM improvements.

Key takeaways

  • Django’s minor version identifies feature releases, while micro versions contain bug and security fixes; projects should use the latest patch release.
  • Django 1.7 requires Python 2.7 and no longer supports Python 2.6, while Python 3 remains supported.
  • Django 1.7 replaces South with built-in migrations that follow the same basic change, create, and apply workflow.
  • Initial data is deprecated because it does not work reliably with migrations; fixtures and explicit data migrations are the safer alternatives.
  • Migration code should use historical models supplied through the migration app registry, because current model methods and definitions may not match the historical schema.
  • The new system check command helps identify configuration and model problems during upgrades, and is also run by make migrations.

Summarised automatically from the transcript.

Chapters

  1. 0:00 Introduction and Talk Overview Andrew Pinkham introduces himself and outlines the talk’s approach to Django releases and upgrading to Django 1.7.
  2. 2:41 Django Version Numbers An explanation of major, minor, and micro version numbers, along with alpha, beta, and release-candidate releases.
  3. 5:04 Support and Deprecation Policy How Django’s supported versions, deprecation cycle, patch releases, and long-term-support releases affect upgrade planning.
  4. 7:22 Django 1.4 Through 1.6 A review of the major features and upgrade considerations introduced in Django 1.4, 1.5, and 1.6.
  5. 12:11 Django 1.7 Requirements and Features An overview of Django 1.7’s major features, with particular emphasis on migrations and the requirement to move beyond Python 2.6.
  6. 13:00 Comparing Django 1.6 and 1.7 Projects The talk begins a practical comparison by building the same Camelot project and Roundtable app in both Django versions.
  7. 16:49 South Migrations in Django 1.6 The speaker demonstrates South’s migration workflow, including schema changes, frozen models, fixtures, and rollback behavior.
  8. 21:30 Data Migrations and Historical Models A migration problem involving initial data leads to a walkthrough of explicit data migrations and historical ORM models.
  9. 26:55 Native Migrations in Django 1.7 The equivalent Django 1.7 workflow uses built-in migrations, operations, dependencies, and automatically generated reversals.
  10. 34:02 Migration Lessons and Caveats A review of Django 1.7 migrations, the deprecation of the initial-data system, fixture support, and limitations of historical models.
  11. 36:50 The New App Registry The app loader replaces the old app cache and provides the historical model support required by the migration framework.
  12. 38:01 System Checks and Upgrade Safety Django’s expanded system-check framework helps identify configuration and migration problems before they cause failures.
  13. 38:48 Additional Django 1.7 Changes The talk begins covering other updates, including queryset managers, the lookup system, and Prefetch objects.

Transcript

8,377 words · auto-generated Show

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

0:20

Hello everyone, can everyone hear me? Is this alright? I'm used to screaming, so make sure the mic's working. So, hi, I'm Andrew Pinkham. I'm a half French, half-American freelance consultant from Austin, Texas. I teach Django in corporate and startup settings, but perhaps most importantly, as Miles just told you, I'm the author of Django Unleashed, which is currently available in pre-release on Safari Books. and is set to be in print form at the beginning of 2015. And uh the book is all about, is currently written in Django 1. 7, and so I've been working in Django 1. 7 in alpha and beta since January of this year. So I've been fiddling with it. I wouldn't say I would know as much as say Andrew Godwin with the talk this morning,

1:05

but I've I've gotten to dabble. And so this leads us into the following talk. There are basically two things that I'm going to really try and talk about The first is Django releases. Uh Django comes with all these numbers. Uh what do they mean? What are they useful for, right? So we're gonna look at the meaning of the numbers associated with each Django release, how each release is sort of created and how they're related and how this helps you figure out how you should go about upgrading around Django. Then we're gonna look at Django 1. 7 itself and what we're going to do is we're going to build a project in 1. 6 and 1. 7 Exactly the same way to try and look at the differences in a very practical manner. Um now here's the thing. If you're uh a migration or a Django enchanter or else the old man from scene 34

1:54

This talk is not for you, right? This is this is supposed to be a very beginner talk about upgrading and all of that. And so if you are any of those things, you're going to be horribly, horribly bored, right? So with that said, uh what I do, I like to put all a whole bunch of material for my talks up online. So you can go to this right now. The slides are already accessible. Uh I have uh a long draft of an article with all of this content almost ready to go. Should be there within the next week, week and a half. And what that means is that if you don't want to listen to me right here, right now, or else on YouTube , you can go to this link and you can actually read the article in a nice relaxed setting. Because I'm going to do a little bit of a whirlwind tour here.

2:41

So let's get started with Django versions, right? So every Django version has Three numbers. Uh that would be a major number, a minor number, and a micro number. Uh let's get this out of the way right away. Uh it is not semantically versioned, right? There is a very strict set of rules for semantic versioning. Django does not follow them at all. Um Django has its own very explicit system. Uh notably Micro numbers are incremented for a release for bug fixes or security releases. Minor uh numbers are incremented for the addition or removal of features and we'll see exactly how that works out. Uh and then major number in the documentation it says that major numbers are uh incremented for

3:29

large backwards incompatible changes. The thing is that in practice what we're seeing is that Django 2. 0 is actually just going to be the version after Django 1. 9. So at this point, they're just sort of associated with minor versions. So not a whole lot of meaning there to be pretty blunt about it. So the thing to remember is that colloquially colloquially, there we are. A Django version refers to a different minor number. So when you hear someone say, oh, it's a different Django version, it's 1. 7 versus 1. 6, right? But 1 is the major number, 7 is the minor number, and 0 is the micro number. There are also a pre-release. There's an entire pre-release system, alpha, beta, typically pretty self-explanatory.

4:19

Um release candidates not everyone is super clear on. A release candidate is uh just a release that is almost ready for production. The API calls and features may not be modified at this time, uh, and you are limited to bug and security fixes. So at that point, it's almost like you're already in micro release process. To separate the version numbers and releases from pre-releases, what the Django Source Foundation will do is they will add a letter and a number at the end. So for instance, 1. 70A1 denotes the first alpha release. You don't need the zero, they'll remove it, so 1. 7 beta 1 uh is the first beta release, and this is the second release candidate. So

5:04

what does that all mean? We now know what the numbers are and how does that help you? Well, Django has two officially supported versions at all time. That means that there are two versions that you should be working with at the very least, right? That's what you want in production on your website. Deprecation happens in two versions. Now what this means is that the release guide is really saying, who shall be the number thou shalt count, and the number of the counting shall be the number two, right? It's a it's kind of important in the Django release. Um the deprecation specifically, anything that is deprecated in 1. 3 will still be accessible but with a warning in 1. 4, but is totally removed in 1. 5. So for 1. 7, anything that was said to be deprecated in 1.

5:51

5 still worked in 1. 6, but is now gone. So it is worth paying attention to two versions back. Uh the two versions that are running, uh so it was released yesterday. Uh nice to be able to change my slides at the last minute. Um support prior to version 1. 7 was 1. 66 and 1. 59. And you'll notice I'm not using the micro numbers. Those patches, you should always be on the latest patch. There is no reason not to upgrade to the latest patch. Um so 1. 6. 6, 1. 5. 9 But with the arrival of 1. 7, we saw a bump in all of the available versions. So 1. 7 brought the arrival of 1. 6. 7 and 1. 5. 9.

6:37

Except that 1. 5 is no longer supported, right? You don't actually want to be running in 1. 5 anymore. It's not going to get security releases, it's not going to get any releases. It's considered done. It's over. Um there's a catch, right? There are two versions, but there's also the long-term support. Django uh the project uh allows itself to tag certain releases and certain versions for long-term support. Uh and what that means is that they will support it for some length of time. LTS for 1. 4 is set to go to March of 2015 Um there is some back and forth over whether the support ends there or they continue to support it, so not really sure. But my recommendation would be You really want to be thinking about 1.

7:22

7 or 1. 6. But we'll come back to that in just a moment. Now that we understand what the versions are, what the versions are Numbers mean, we can talk about the previous Django versions. This will help inform us about 1. 7 and the upgrade process. Right? So the obvious thing is that, well, we're talking about 1. 7 and 1. 6 is is currently supported, so we want to know a little bit about those. But 1. 5 is Going to affect the deprecation process in 1. 7, and so that's still important. And 1. 4 of course is actually supported because of LTS. So let's start with Django 1. 4. Django 1. 4 started off with time zone support, right? That was the big new thing. It saw a couple additions to the ORM, such as prefetch related kind of But also some really basic stuff like cookie based session handling.

8:12

Passwords prior to this were stored all in SHA -1, and this was when we saw the public key derivation function two come in, as well as bcrypt. That's that's huge, right, for security. That's that's a major upgrade. And then of course functional browser testing and a new structure for your folder. And so 1. 4 was pretty massive. It's also why it's for LTS. 1. 4 is arguably, I'm not sure uh everyone would agree with me on this, but is is arguably modern Django, right? It's it's sort of the beginning, yeah, I'm getting a couple shakes of the, you know, that's nice, okay. Um Which is why, so this was March of 2012, and so in February of 2013, we had Django 1. 5 Django 1. 5 felt like a much smaller upgrade, right?

8:59

So 2. 5 uh Python 2. 5 was dropped, um, so you had to be in 2. 6 or 2. 7, and there was experimental support for Python 3. You could try it. It wasn't recommended. It was more like, hey, test this out. Give it a go. Um we saw the custom Django user and uh the function-based views that had been deprecated in 1. 3 were completely removed. in favor of the generic class-based views which currently exist uh and which I'm actually a huge fan of. Um despite anything else. So um it it felt kind of small, but you really want to pay attention to that jang that Python 3 support. That's actually a a huge deal and was a lot, a lot of work. Now the thing about 1. 5 is that the upgrade was nonetheless still really tricky.

9:44

And the reason is that there were mandatory settings in deployment and they weren't always obvious, right? It wasn't always obvious when you went to deploy what was going on when it aired like crazy. It's because you needed used time zone, allowed host, you need to make sure you have a secret key, otherwise it it went nuts. Um And this is this is actually kind of important because this I think uh you'd have to ask Russell um but I think this this may in fact be the reason they actually have the what is originally the validate command and what has become the check command in 1. 7. So pay attention to those settings. We'll come back to it. Which then led to 1. 6. And 1. 6 was huge, right? So Um still 2. 6, but Python 3 support was now totally official, and we had transactions completely redone,

10:32

spearheaded by Emery Augustin. And so uh transactions hadn't been changed since version 0. 9 And suddenly you could auto-commit database changes. There was the concept of atomicity via decorators, and then there was fine-grained rolledback between save points, if your database supported it, and persistent database connections. Finally, uh settings got super easy. If you were a beginner in Django and you showed up in 1. 6, your life was incredibly simple compared to all the previous versions. There was a Baster in settings, which was lovely. The SQL Lite database was now a default. Admin was turned on by default, and so was clickjacking. Well so that that was super, super cool. This is where uh on the other hand we also see the validate command. This was to try and help with with figuring out basic setting differences, what was wrong.

11:23

And it was it was a nice step, right? It gets us to where we want to be in 1. 7 The only trick was was that uh with the upgrade here, uh if you'd done funny things with transactions, you were you were in trouble. Um but the other thing is that uh we see the beginning of a trend where Django begins to remove a lot from the contributed library. This is where comments, markdown, and local flavor really get taken out. Um that leaves us with Django 1. 7. Uh for those who missed it, this was what Russell wrote on the Django web blog. right before selling us t-shirts, which he's wearing today, by the way. If you can catch Russell, that is that is in fact the the t-shirt he sold us all. So it's it's kind of a big deal. Um these are some of the features, right? And we're gonna focus mainly on those top three because that's what we've got time for.

12:11

And this was released, of course, yesterday. So this is going to be a World War II. And I want to try and take, I've heard some people who are just a little bit afraid of the migrations. There's nothing to be afraid of. They're fantastic. You want these. Get excited. Now I haven't put the Python version on here. And that's on purpose. Django 1. 7 requires Python 2. 7. It's going to be maybe the most difficult part of the new requirements for this version. So of course Python 3 is still supported, um, thank goodness. Um but if I could if I could really get this to be the one thing you take away, I Python 2. 6 is no more. It has ceased to be. It's expired and gone to meet its maker, bereft of life.

13:00

It rests in peace. This is an X Python. Don't use it. No, really, just I I want you to take this as like word of God for me here, right? If I could get one thing, please. Please, and really consider upgrading to Python 3. It's gonna be really important pretty quickly. With that said. Uh let's jump directly into building a project in Django 1. 6 and Django 1. 7. So we're going to build a project called Camelot. We're going to build an app called Roundtable. And we're going to build a night model. And what we're going to do to demonstrate the three key new features is that we are going to take our nights, we're going to create a really, really basic model.

13:45

And then we're going to be betrayed by Lancelot. So we've been asked by King Arthur to build this up and to get the information out there. It's good publicity. So Again, these are the three things we're really going to focus on. And the rest is really, really cool. You should take a look, but this is what we're looking at right now. Now, uh the reason for that is because this is a total rabbit hole. There is so much here and it's really really cool. But this is what we're going to end up like if we spend too much time here. So this is a whirlwind and the I'm going to show a lot a lot a lot of code The code is actually not what's important in the coming slides. I've put it there and in all its glorious details, so you can download my slides, you can go through the article. The article actually has more code. So you can you can actually go through it more slowly.

14:32

What's much more important is sort of the philosophy and the workflow that you're going to see me go along, right? So that's the focus and the code, you know, come back to it, but let's have a first pass at it. So let's start by creating a project. You guys have all done this. Um and so the first difference is that in Django 1. 6 you had Django Admin, and there is now a nice alias so that you can just do Django admin uh without the dot pie. The structure of the folder looks almost exactly the same. The only difference is that in settings there is a session authentication middleware which will invalidate existing settings in the event a user changes their password. Which is super cool. Um and there is also in the URLs one small change. There is a line missing. It's admin. autodiscover.

15:18

It's gone. Now admin is still enabled by default, but this is major foreshadowing for the new app framework. So we'll come back to it. Now at this point in our 1. 6 framework, uh it's one point Django 1. 6 project, uh we normally the best practice would to be uh to run syncdb right now. Right, so just just as a heads up, when you're you're doing this in 1. 6, if you're following along, run sync db now. I'll say it again. Uh at this point you can create uh the app in both Django 1. 6 and 1. 7 and it's Exactly the same with the exception that in 1. 7 you automatically get the migrations package. Right? It's it's in bold. Um now we can go about creating a night app. Uh so there's a little trick here Which is that this would be fine, right? It's a night model. Yes, night, not night app, night

16:04

model. And it's very straightforward. We have a name, uh, and then we have the string representation for Python 3, right? This is Python 3 Um the problem is is that doing this in South, we're doing it with South 1. 0, which actually introduced a regression so that you can't actually currently run in Python 3. So our Django 1. 6 is going to run in Python 2, and our Django 1. 7 is going to run in Python 3. And so we have to do a little bit of shenanigans to get it to be. Running in both. Um the future import Unicode literals makes sure that everything runs in Unicode. Native strings are now Unicode. And then we have a decorator, which is super cool because in uh the string representation in Python 3 is stir, but in Python 2 it's Unicode.

16:49

That decorator ensures that it works in both. Right. Um about the bug in South 10, uh there is already a bug fix for it. It's just simply not released, uh, and this seemed like fun. So Now that we have a uh project, we have an app uh and we have a model, we can go directly into Migrations. Right. So the history of migrations you heard a lot about this morning. Just to recap, uh Andrew Godwin created South in 2008. It quickly became the de facto tool for schema and data migrations. Uh and in 2012 Andrew began asking around about the API for South 2 or else migrations in Django. He kickstarted in March of 2013 and he'd initially set a goal.

17:35

He avoided this. He was very modest about this this morning. He initially set a goal for uh 2 ,500 pounds, uh, which was met in just over an hour. The stretch goals, which had a maximum of of 7,000, followed like several days later, and they continued to 7,952 pounds. Which at the time in dollars was 27,397. That's a lot of money for this. And it's it's actually a really good thing this happened because migrations are cool. What is a migration? So I'm sure there's some people in here who maybe have avoided South, you have little projects, you haven't had to use it. And the way to think about migrations if you haven't seen them before is version control for your database scheme.

18:23

It's not a perfect analogy. You know, there's all sorts of problems with that analogy, especially because you're putting your version control in a version control, oh that's going to get ugly. But the bottom line is that it helps it so that you don't have to make manual changes on your database when you make changes to your models, right? Super helpful. And the workflow here is that you are going to make a change to your model. You are then going to create a migrations file some way, we'll see. And then you are going to migrate or alter your database using the instructions in your migration file. So, we sort of did all of that in 1. 6 and 1. 7. So now we're gonna focus on just 1. 6, right? So again, we created a project, we Uh added south to settings.

19:08

py, we then called sync db, and then we created the app, right? So we already have a database at this point, but everything else should be fairly straightforward. So at which point we call schema migration initial. We tell it just the first one and it goes ahead and says, oh hey, yeah, let me just go and look at your models and create a migration file. That migration file looks like this, right? There is a class, and there are four things to it. We're really only interested in those first three. The forwards method, the backwards method, and the models, which are referred to as frozen models. So the forwards method is just what gets called when you tell it to change your database, right? You can see it's just creating a new night table There is no magic here. The backwards is the opposite, right? It's totally symmetric to

19:54

forwards, and so it just deletes the night model. So the weird one, so that's fairly straightforward. The weird one is models, right? It's referred to as the frozen model, and it's not immediately apparent what it does because it's just kind of sitting there. We'll come back to it. Once we have our migrations, we can just say hey please apply this and it goes ahead and does just that You'll notice that last line, installed zero objects from zero fixtures. Well that's super helpful. You know, we'd we'd gotten King Arthur who'd said, well, it'd be really nice if they could download this from the Git repo. and immediately know who all the nights are. Well so we can use this initial data system with fixtures to go about and head doing that So we are going to pop into the Django shell. We're going to create a whole bunch of knights.

20:40

We make sure that they're there. And then to make sure that everyone has them. We're just going to use the dump data function, we're going to slam it down into a JSON file, and we call it initial data. Django already knows to look for that. And so if we roll back our database and the reason we can do that again is because of backwards, right? It's just going to delete it. Uh and then roll it forward, you can see that it's installed those seven objects, which means that if we include that with our project Everyone will have the list of knights. That's great. King Arthur's happy. Until Lancelot. Damn it, Lancelot. Okay, so King Arthur shows up and he goes, Well, I need a new field. And I need you to uh to deal with Lancelot in the database. And so you go short, no problem. So you add the field, and then you say, hey, I want you to automatically figure out what I've changed in my models.

21:30

And South goes, yeah, no problem. And what it's doing is that because it can't rely on the content in the database, right? It doesn't actually know what's in there, can't trust what's in there. So what it does is it looks at what's in the models and it looks at the frozen model And it does a difference between the two to figure out what's new. And so now you know the purpose of the frozen model. So it will use this to automatically generate this. Now, I intentionally left an error over here, which I forgot to mention when I brought it up. The Boolean field. uh should have a default. As of 1. 6, you need to have a default equals false. I am intentionally leaving it out, right? So fast forward. So when we call round table auto South tells us that it doesn't know how to fill it in, but it doesn't tell us it's a problem, right?

22:18

So what I've done is I've simply said, oh well by default, no one's a trader, right? False. At which point we can m migrate the round table and you think everything's going to work just fine and you're wrong. Right. What happens is Django pukes data at you to be crass about it. Um it's just going to start really, really complaining. And what's happened is you've tried to load the JSON and it doesn't know what to do with the trader fee The initial data doesn't have it. And so Django just freaks out, which is good. That's what you want it to happen. Any sort of implicit behavior there could be really, really dangerous. But that means that our initial data problem, the initial data system, is a problem when used in tandem with migrations. So let's step back. We're going to get rid of the migration file that we just created.

23:05

We're going to delete the trader field, and we're going to deal with this problem first Let's roll back the database. That's that first command. We're going to move the initial data so Django doesn't look for it automatically. I'm going to give give it a funny name. We'll see why in a moment. And then we're going to reapply that first migration so that we have the structure of the night model in our database, but not any data in there, right? And you can see that at the bottom it says installed zero optics from zero fixtures. Now at this point, we want something like the initial data system, but we don't want the initial data system. So we're gonna go ahead and create a an and a data migration. And the data migration is simply a migration, frozen model and all, except that the forwards and the backwards are not implemented, right? You are expected to write these functions.

23:52

And this is where it gets really cool, right? Because you can rely on the fixture system, right? Not the initial data system. You can rely on the fixture system. And just call it directly and say, hey, I want you to use that JSON file that we still have. And that's in fact why I named it that. So that you can can help figure it out. The thing is this is pretty silly, right? You've got two files basically to generate data in your in your um database, and you can do it all in one. Now you can see that that's that doesn't look quite the way it should, and you'll notice that there's an ORM before the night. The thing when doing a migration is that you don't know if the models in your database are what you want So South will create the historical model and will put that in the ORM so that you can then use that

24:38

to actively and correctly give it what it expects. So that's why there's an ORM. Um and that's a big thing about the new migrations as well, which we'll see just in a moment. So now we roll back the database again, we bring it all the way back up, we see our initial schema is now applied, and we see that our um Our initial data is also initial data. The data generation process is also applied, and so we have everything that we want. Now we also want to program our backwards because we're good developers and we want this to be symmetric, right? And so that's very easy. We use RRM and night again, and we just say, well, delete everything in the database, right? Everything we just added, just remove it. Fantastic. What this means, of course, is that we can actually roll back, right? We were in 002

25:23

or 0002, and we're now going to 0001. And at this point, you know, if we go into the shell and we ask for all the knights, they've been removed. So this is this is really cool because you can move backwards and forwards in the migrations, either adding data or removing data, and this is the safe way to do it. At this point, now that we have the data we want in our database correctly without any reliance on the initial data system, we can go back and add our trader field. It's still wrong on purpose. We get exactly the same output as last time when we try and automatically generate it. Um so we're going to again say it's false. Everything is default false. Um and then we migrate and everything works just great, right? And that's what you want. So at this point, uh

26:09

we have the new trader field in there. But the problem is that if you go into your shell and you ask if Lancelot is a trader, which was really the original point here Um it says false, and then Arthur is not happy with that. So you go ahead and you create another data migration. You then fill in forwards yet again where you simply say um Uh you know, or M knight, find Lancelot, set him to traitor, and you remember to save. And the backwards, right, again, because we want this to be as symmetric as possible. Um the only difference is that we're now setting it to false. So if we migrate all the way up with our fourth migration, Lancelot is now a traitor. And Arthur's happy. Now, let's do it all again. So I'm sure you guys are excited.

26:55

Um So uh again in 1. 7 we didn't need any of those beginning shenanigans, right? You just start the project, you get into the project, you create an app, and then you can immediately go straight to programming your models. You don't need to worry about sync DB it's It's far away from your mind. So this is exactly the same model as we had before, but just with the name, right? The trader is gone. We're at the very beginning of this project. And we can go ahead and instead of schema migrations, we're going to call make migration. The output's really, really pretty. You can't see it on this screen because I couldn't get the color coding to work. But in my bash terminal, it's color-coded. It's gorgeous. So at which point it will create this guy. This is totally different, right? There were four things in the last data migr in the last migration for South, and in this one there are

27:41

only two. So dependencies is at this point an empty list, right? So if you heard Andrew Goldwyn's talks, you know what's coming on that front. But what we really care about are operations. And the operations currently looks like this. And you can see what it's doing is it's creating a model. It knows that it's going to create this in the database. You'll notice there's no backwards, right? Operations is strictly forwards. What's super cool about the new migrations is that they figure out automatically what the symmetric opposite. is. I don't think that's probably the right mathematical term there. Sorry. Now with that migration automatically figured out, we can call migrate, at which point it will migrate everything that we need, including on the second to last line, our round table. At which point it should come as no surprise that initial data no longer works, right?

28:31

It's been deprecated in Django 1. 7 because it doesn't play well with migrations And so at that point, we are forced to use data migrations, right? And that's super easy. Except instead of asking for data migrations, we're simply going to ask for an empty migration file. So we go ahead and do that and that name is horrible. That is that is so unhelpful. So I don't know if this is standard practice because I don't think It's been around long enough for there to be a standard practice. But I've been renaming these um because that's that's the time and date that's supposed to be created, and that's not interesting. It doesn't tell me anything. So I'm renaming it to Ad Night Data, at which point we come into here and Um we need to fill this in. So as Andrew mentioned this morning, there is a really helpful command called runPython, which takes essentially two things, the forwards method and the backwards method.

29:20

So it's very similar to South, right? It's what do we do going forward and what do we do going backwards? And so here what we're going to do forwards is add night data, and when we go backwards, we're going to remove the night data. The second one is actually optional. You need to put in a reverse code keyword. And then just like with South, we could rely on the fixtures, right? The initial data system is gone, but the fixtures aren't, right? Fixtures still work just fine if you want them and need them and there's still projects that are gonna make really good use of them like classy class-based views makes a has a really good example for how to use fixtures So we could do this. But again, this is pretty silly because you now have two files for one thing. And so I advocate um

30:05

with absolutely no basis, the act of doing this. Now this is slightly different, right? Apps. get model roundtable night. Ooh, it's the new app loader. But we're not getting it from Django directly. You'll notice it's being passed into Adnite data, which gets an apps and a schema editor. So Andrew talked this morning about the schema editor. It's basically what does the actual database altering and manipulation. But the apps is the historical model. It is not what is currently in your models, it's what the new data migration or the new migration system expects there to be in the model, and that's actually really important. So when you do this You want to make sure that you're pulling from apps. Otherwise things are going to go completely bananas.

30:54

So we then go ahead and create everything as we would expect. And uh again, once again, because we're uh Dedicated to being symmetric and good programmers, we go ahead and do remove night data. And again, you can see me using the new app uh loader and just deleting all of them. And we get to relive Lancelot's betrayal at this point. So we add the trader field, and you'll notice again I'm intentionally making an error. Now here's the thing. Before we look at migrations, let's step to the side. We avoided the my manage. py validate, but let's run check. Ooh, it knows there's a problem. It warns us there's a problem, and in fact, it will tell you where in the docs to look. to figure out how to fix that.

31:41

That's really cool, but what if you forget to run check? Well Django's got you covered because when you run make migrations, it'll run check for you and it'll yell at you, right? Giving you all of the same information, which I've helpedfully removed from the slides so you can see the rest that it outputs. Uh which which is as saying exactly like South, what do you want me to fill in? So it's going to warn you, but it's then also going to say, hey, we can keep going forward. And you could. You could just say, oh, well, you know, the default is false and and just kind of keep going. If you hadn't listened to Czech so far, it's going to keep yelling at you, right? When you migrate it, it's going to say, hey, you you really, really, really don't want to be doing this.

32:28

So the bottom line is that Django will let you shoot yourself in the foot. Don't, right? Don't shoot yourself in the foot. When Django check warns you that there's a problem. there's a problem, so do pay attention to the output of these commands, right? Don't just gloss over them because it's in they're now incredibly helpful. Right? So of course, we're going to pretend that we didn't have make migrations and then migrate. We're going to add the default false. We will then go and run make migrations. We will get a correct make migration and we will then migrate that. And we end up with the same problem as before where yes, we now have a trader field in our database, but Lancelot is still not labeled as a trader. So we once again make an empty migration file instead of data migration. We can rename it, I think.

33:15

Again, not clear on that. And uh we can then uh invoke run Python as the operator and we will program setLancelot status to go forwards and unset Lancelot status to go backwards. So the set Lancelot uh Oh, whoops. Set Lancel that should read set Lancelot Trader and Unset Lancelot Trader. So that's set Lancelot Trader. And again, we're using the new app loader. And we set it to true. And the unset is exactly the same thing with the the app loader and all of that, except that we set it to f false at which point we can migrate this new data migration at which point Lancelot is now a filthy dirty trader. Wow, okay, that was a lot of content

34:02

real quick. Where am I going with this, right? What's the point. Let's review what we just saw, right? The three big features. So the first were migrations, right? This is the big thing. It's what to take away. And hopefully you're a little less frightened, right? It's there to help you. It's super easy. And so you wanna you wanna like really uh take some time. Oh, do I not have an hour? Uh 15, 15 minutes. Oh, okay. Whoopsies. Okay, there we go. Um so ha ha ha ha. So the initial data system is deprecated, right? That should come as no surprise given our last example. Our fixtures still work, though, however, right? The two are related but not the same.

34:50

And the frozen model is gone. This slide is shamelessly stolen from Andrew Godwin because he's used it in his last four or five presentations. And it shows you why the frozen ORM is gone. It takes up a lot of space. And one of the big features of Django 1. 7's migrations is that you're supposed to be able to edit them. Right? Those files were very small and we went directly into them and we had no problem fooling around, right? Because they're very straightforward. So the historical model, right. uses the app loader to build it directly in memory and keep it there. And that helps see the utility of the dependencies, right? Every migration has a set of dependencies which it then uses the app loader. to build this historical model for, which it gets to act on.

35:36

There's an important caveat, which is that when you are using these, uh the methods you define on your actual models will not get used. So you have to be very careful. So if you've overridden save and you try and use it in the historical models in a data migration, it will not work. It's just going to call the default. Um there's also currently a bug in 1. 7, or I don't know if I'd call it a bug. It's a problem. Where if you have tons and tons and tons of models, it's going to freak out. It's just going to take absolutely forever. There's currently a uh Bug them being there's a it's on the tracker and they're looking at 1. 7. 1 to try and fix that problem. Um

36:21

but the key takeaway Migrations in 1. 7 have exactly the same workflow as the migration as South migrations, right? You change a model, you create a migration file, and you apply the migration. And that's really cool because if you've used them before in South , there's no real overhead here, right? So about South in 1. 7, South does not work in 1. 7. If you're in 1. 6, you're using South migrations. If you're in 1. 7, you're using native migrations. You can't sort of overswap the two or overlap the two rounds. If you're going to upgrade from South, the instructions are in the docs and they're kind of hysterical because it says bring it up to the latest migration, create a new native migration, delete South. You can just get rid of them. Um so uh because Django knows not to use South. It knows the difference, and so does South as of version 1.

37:10

0. But just in case you want to keep them around, there are two settings both for Django and for South so that you can help avoid any sort of namespace conflicts if you need it. You probably won't. Now if you don't want migrations at all, I don't know why you wouldn't want big migrations at all. Don't follow this advice at all, right? Like don't get rid of them. But you can. And then you know No, I'm not sure why you would do this. Um that leaves us with the app loader. So uh prior to 1. 7 it was called the app cache, and Andrew Godwin on his blog referred to it as the Borg because it shares a state across every single instance of it. It's totally incompatible with migrations because migrations needs those historical models to act on, right? So it was one of the first things to go given migrations was going to come up and it led to the new app registry

38:01

Basically, this has been coming for since 2007. It's been worked on by a ton of people, but basically, I'm under the impression that migrations was what finally pushed it over the edge. When in May of 2013 Andrew Godwin began to change it so that migrations would work. Emery Gogustin in December of 2013 picked it up. took all of the workhead that had been done, reduced it to seven items, and then focused on three. It's on the developer, uh the Google developer mailing list. It's an incredibly good read. I really recommend it. Finally, there was the systems check The system check, I really think, I have I have no basis for this, um, that it has to do with the 1. 5 upgrade where we had problems with use TZ, allowed host, and secret key. This is going to seriously help anyone do any upgrade, avoid any kind of pitfall, all of that.

38:48

The work uh for 1. 7 was done by Christopher Madrella and overseen by Russell Keith McGee. And basically they took the validate check, which was a little confusing and totally monolithic, and turned brought it out into a whole bunch of different pieces. And what that means is that you can now actually use the check, right? This is from the documentation You can actually invoke it directly so that you're performing checks on your own stuff. Please do. There are a couple other changes I just want to talk about. Um there's um the query set you can now set as a manager, so you only have to define the query set rather than overloading both the query set and the manager. Um there's a new lookup system and there's a prefetch object to help with prefetch related. Uh there's a talk tomorrow at 1030 a. m. in ballroom one with Christopher Adams about learning to optimize Django with prefetch related.

39:35

Uh I think it's unfair to expect any sort of coverage about the new prefetch object, but it'll really help you get to the place where you might understand the object better. I really would like to tell you that preparing to upgrade revol involves nothing. Um I'd be lying. Uh the upgrade process, however, is fairly straightforward, right? You look at your dependencies and you figure out what you need to upgrade. Well, if you're on 2. 6, you don't want to be on 2. 6 anymore. You want to go straight to 2. 7. Third-party apps, are they still supported? Are they still working for you? You are they helpful? Are you on the latest version? Is there a version for the next one? Right? You then take the release notes for the version you're upgrading to and you just go through it. It's a tedious process, but it is the safest way to go about this because

40:22

You hit everything, right? At which point, you run your test suite. If you don't have a test suite, um please buy Harry Percival's book. It's a really good read. No, it's a fantastic read. Uh and it'll be super helpful, please have a test suite. It will be so helpful. Um Now again this is a tedious process, but it's not the worst thing, right? Everyone says it's the worst thing, but please take the time to do it and in fact schedule it. Right? One of the big things is that you really need to think about this. This is now, you know, there is a release schedule. You should expect this to happen Um upgrade early, upgrade often. If you have a lot of little upgrades to do, it's way better than having to do 1. 1 all the way to 1. 7. You should not be running 1.

41:07

1. Right. At the very least you should be at 1. 4. And you can start upgrading uh at the release candidate, right? Once the release candidate is out, they're saying, well, this is mostly good enough. And that way you can actually help the Django project by providing bug fixes if it isn't working for you. The final thing is that I I think people look at this wrong, right? They say, oh, we have to like schedule all this time to get upgraded. No, you have to invest two weeks, a month, to get hundreds of hours of really good work from hundreds of other developers. And people really need to start looking at it like that. It's a major investment, yes, but the return on it is enormous. Um and it's getting a little scary.

41:53

Uh so this is what so so uh this is how long The the each version was the principal version, right? So 1. 6 had 1. 7 made the May 15th release date would have only been around for 190 days, and you can see that that curve is pretty terrifying. Now they didn't make that, right? This is this is what the actual was, and that's a little bit more reasonable. But you can still see a trend where they're trying to have shorter releases. So it's going to be increasingly important that you stay up to date, right? So let's review some practical knowledge. Django 1. 7 means the death of 1. 5. Get off 1. 5. It's not on LTS support. It's gone. And if you're on 1. 4 and saying, oh, well, we can sort of stick around, well, remember that it might be over in March of 2015.

42:43

That's not all that long, right? They they might decide to extend it, but there's no guarantee. So really consider an upgrade up to 1. 6. Now why not 1. 7? 1. 7 uh Depending on what you need, might have a few kinks to work out which might which look like they're all going to be sorted out in 1. 7. 1. If you can get to 1. 7, please do, right? But if you have an enormous project with the models that are completely nuts, take it slow, right? Finally, uh so we've talked about iterating through each version so that you can do the release process. This will help with gotchas. One of them is that uh the passwords, uh the password URLs in 1. 5 are base 36. When you go to 1.

43:29

6, it's base 64, but 1. 6 knows this. It catches it. So if you do 1. 5 directly to 1. 7, it doesn't know to catch it. And that's going to be a problem. So you do want to really take your time going through each version. SyncDB is dead, long live migrate. Initial data fixtures are dead, long live data migrations. And remember that when you're dealing with all this, the fields need deconstruct. It's also important to look ahead to the future. I realize I'm I'm straining on time here, I'm sorry. There is a deprecation release uh document uh on the Django website. It will tell you things like, oh, your all configurations are going to change in 1. 8. There will be no patterns. It's just going to be a list of calls to URL. You will need to use direct imports.

44:14

Knowing that can help get your code right before it's even released. So it's a really good idea to look at that. I'd like to thank the developers who documented all of their changes. Emeric Rot wrote a fantastic email. Uh Russell wrote a fan fantastic set of emails about the changes and Andrew Godwin documented all of his stuff on his blog. It's been a joy to read and I really hope that the uh the talk about the DEPs, like the Python enhancement proposals, but for Django, come along because that documentation I think would be even better. Questions? Do we have time?

Questions this talk answers

What do the three numbers in a Django version mean?

Django officially supports two versions at a time, and deprecated features are generally removed after two releases. The talk recommends targeting Django 1.7 or 1.6 and always applying the latest micro-level security and bug-fix release.

Discussed at 5:04

What Python version does Django 1.7 require?

Django 1.7 requires Python 2.7; Python 2.6 is no longer supported. Python 3 remains supported, and the speaker strongly recommends considering a move to it.

Discussed at 12:11

What are Django migrations and how do I use them?

Migrations are effectively version control for a database schema: change your model, create a migration file, and apply it to the database. In Django 1.7, `makemigrations` creates the migration and `migrate` applies it, with Django automatically generating the reverse operation where possible.

Discussed at 18:15

How do I write data migrations in Django 1.7?

Create an empty migration and use the `RunPython` operation to define forward and reverse functions. Retrieve models through the migration’s historical app registry (`apps.get_model`), rather than importing the current model directly, so the migration works with the schema state it expects.

Discussed at 28:20

What happened to Django’s initial data system in Django 1.7?

The initial data system is deprecated because it does not work reliably with migrations. Fixtures still work, but data that must be created or changed as part of a migration should be handled with a data migration.

Discussed at 28:31

What does Django’s `check` command do?

The system check command validates project settings and configuration and reports problems with guidance about how to fix them. `makemigrations` also runs these checks, so it can warn about issues such as adding a non-nullable field without a default.

Discussed at 30:40

How do I upgrade from South migrations to Django 1.7 migrations?

First bring the South migrations up to date, create a new native Django migration, and then remove South. South migrations are used with Django 1.6, while Django 1.7 uses its built-in migration system; the two systems should not be mixed.

Discussed at 36:36

Presenters

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

More videos by Andrew Pinkham

More videos from DjangoCon US