In a (futile) attempt to future-proof the book, I decided to upgrade it to Django 1.7. Here's how that went down.
Unsurprisingly, the biggest change was to do with migrations. Like any new change, my initial reaction was dislike, and I resented the new things, but I think overall it's a definite improvment.
In brief, here's what happened:
The new migrations framework means 'any' change to models needs a migration, or tests won't pass.
This meant introducing the concept of migrations much earlier in the book; in fact, at the same time as I introduce the ORM. I resented this because it made the learning curve of the book steeper.
On the other hand, because the new version of migrations essentially forces
you to have them from the very beginning, I was able to drop an entire
chapter that was devoted to retrospectively building migrations after the
first deployment, which included all sorts of checking out of old versions,
--fake, and so on. So that's a big win.
Using step-by-step TDD also forces you to make more migrations than you really want to, if you're adding fields and constraints step-by-step. It means I have to introduce the reader early on to the idea of replacing existing migrations too, another steepening of the learning curve.
Here's some detail on the changes.
In chapter 5, where we build the first model, the narrative used to go:
Now it goes:
So you can see it's more complicated. On the other hand, understanding how Django gets from models.py to the database is important. I had been just hand-waving and saying "use syncdb, and just delete the database if anything goes wrong", so maybe it's better to address this stuff head-on, rather than wait for a complicated later chapter.
If you're curious, you can view the whole narrative here
(If you're a Django core developer and you're reading this, I'd love to hear your thoughts btw. There's a few weeks before the book goes to print yet, so there's still time to tell me I'm doing it all wrong!)
I still kinda wish I could have kept my nice shallow learning curve - I expended a lot of effort with the book, in trying to make sure concepts are introduced one at a time and gradually, and now I feel I'm slightly forced to lump two concepts onto the reader at the same time. But, there's clearly an upside.
It was always going to be an unlucky chapter wasn't it. Because I'd glossed over the concept of migrations until then, I would get the readers to deploy their code to a server in chapter 8 or so, and then code some new stuff, including a new database feature.
Then I had a chapter 13 in which we would try and deploy to the staging site, and see the new feature wouldn't work. So then I had to explain migrations, and go through this process:
manage.py schemamigration, and create a migration to match live
schemamigrationto get the migration we want to apply.
migrate 0001 --fake, then check out the new code, and run
migrate, check it works
migrate 0001 --fakefollowed by a
migrate 001 --fakefrom your deploy script.
Ouch! Quite a lot of pain there! Especially when you consider that the new procedure is:
I found the fact that tests would fail if you didn't have migrations intriguing,
but unfortunately it's not something you can rely on. For example, in chapter
12 I introduce a
unique_together constraint and test it thusly:
def test_duplicate_items_are_invalid(self): list_ = List.objects.create() Item.objects.create(list=list_, text='bla') with self.assertRaises(ValidationError): item = Item(list=list_, text='bla') item.full_clean()
To get that passing, I just add my
class Item(models.Model): text = models.TextField() list = models.ForeignKey(List) class Meta: unique_together = ('list', 'text')
And at this point Django doesn't warn me that I need a migration, because the test is actually happening at the validation layer.
I think that's a bit of a shame, but there's probably nothing to be done about it. It's all because the concepts of data validation and database integrity constraints are separate in Django, even though their implementation in models.py actually often happens in a single place...
I love the pretty colours!
I'm writing a book all about TDD and Web programming. Read the draft and let me know what you think!
"Hands down the best teaching book I've ever read" — "Even the first 4 chapters were worth the money" — "Oh my gosh! This book is outstanding" — "The testing goat is my new friend" — Read more...
A selection of links and videos about TDD, not necessarily all mine, eg this tutorial at PyCon 2013, how to motivate coworkers to write unit tests, thoughts on Django's test tools, London-style TDD and more.
This is my old TDD tutorial, which follows along with the official Django tutorial, but with full TDD. It badly needs updating. Read the book instead!
The campaign page, preserved for history, which led to the glorious presence of the Testing Goat on the front of the book.