Django Has Changed Over Time

Repetition is king for learning. Working with models, views, and templates over and over gets repetitive, but that’s a good thing.

Have you ever seen a tutorial online and thought, “That code doesn’t look very familiar.” No repetition, no knowledge.

Usually these differences are not WAY off. The similarities give you sense for what you have to do. But after you give it a shot, you get an error.

One of the biggest reasons to start your web development journey by learning Django is because it is OLD. Old things are set in their ways. They won’t change so much on you as you slog along.

In fact, this was one of the biggest reasons I decided to pick Django as my learning language. You can be sure that you won’t lose much on your investment because what you learn will still be relevant in the future.

But still, things have changed in Django. And this makes it difficult to learn on the internet. There’s a lot of wasted time. And time is more valuable than money.

To help save you time, I want to outline some of the major differences I’ve run into while learning Django.

When reading a tutorial, attempt to find out the version of Django the author is using. You can view changes in the Django release notes.


Before version 2.0, Django used a url() function to add a URL to your urlpatterns list. Here’s a link to the 1.11 django.conf.urls documentation.

Django 2.0 added path() and re_path() functions for putting URL items in your urlpatterns list in Here’s a link to the 2.0 django.urls documentation.

They function similarly, but url() will likely be deprecated in the future.

Import statements

Import statements have been the single biggest challenge for me. With all of this DRY, reusable code, there is this complex web of python files. It’s kind of like navigating through a maze: you can see the path ahead of you, but you need a memory sense of everything around you if you’re going to make it out of the maze.

The design is fantastic, but it’s difficult to pick up.

If you get an ImportError, it’s possible the file you’re looking for has just been moved. Make sure to read the error because it might tell you what’s going on. Then, as always, Google is your friend. You may even want to search directly on the Django Documentation.

An example to note that tripped me up recently: mapping urls.

You may have noticed in the previous section that the import path is different for those URL functions.

Previously your import statement at the top of your file would be:

from django.conf.urls import url

In Django 2.0, it looks like:

from django.urls import path

Another thing to note: the include() function for including other urlpatterns has followed this move, located at django.urls.include() in Django 2.0.

Python print statements

Python 3 had a major update in print statements. Here’s the differences listed directly from the Python 3 Release Notes.

Old: print "The answer is", 2*2
New: print("The answer is", 2*2)

Old: print x,           # Trailing comma suppresses newline
New: print(x, end=" ")  # Appends a space instead of a newline

Old: print              # Prints a newline
New: print()            # You must call the function!

Old: print >>sys.stderr, "fatal error"
New: print("fatal error", file=sys.stderr)

Old: print (x, y)       # prints repr((x, y))
New: print((x, y))      # Not the same as print(x, y)!

Help us all!

Got another example? Leave a comment below because others are having the same problem!

Get Notified of New Posts

Sign up for the newsletter and I'll send you an email when there's a new post.