Django Best Practices: Imports

Updated Best Practices

Table of Contents

Imports are an inevitable part of Python and Django development. PEP 8, which is the official style guide for Python, recommends imports be placed at the top of the file, on separate lines, and grouped in the following order:

  1. Standard library imports
  2. Related third party imports
  3. Local application/library specific imports

Whenever possible, be as explicit as possible with imports.

Absolute vs Relative Imports

Here's an example views.py file from the Blog app built in my Django for Beginners book.

# blog/views.py
from django.views.generic import ListView, DetailView
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy

from .models import Post  # explicit relative import


class BlogListView(ListView):
    model = Post
    template_name = "home.html"

The top 3 lines are absolute imports which are used when importing packages from outside a given app. This is how all Django core code is imported.

The database model is imported using an explicit relative import--we didn't hardcode the app name in here which makes it much more reusable. If we had instead done from blog.models import Post then if the name of the blog app changed in the future or we wanted to separate out this code, the import would fail.

Wildcard Imports

Another good rule of thumb is to never use * which accesses all imports. For example, this is a bad idea:

# blog/views.py
from django.views.generic import *  # BAD IDEA!

Why import things you don't need? More importantly, wildcard imports pollute the namespace and make it impossible to tell at a glance where a given name came from. This makes debugging harder and can cause subtle bugs if two modules export the same name.

isort and ruff

Don't want to worry about manually sorting your imports? isort is a dedicated Python utility that will automatically sort and group imports according to PEP 8.

If you're already using ruff for linting (which is recommended), you don't need a separate isort install — ruff includes isort rules built in. Running ruff check --select I . will check import ordering, and ruff check --select I --fix . will fix it automatically.

Takeaway

You'll likely see different import styles in open source and professional code settings. Try to follow PEP 8 as closely as possible. Use absolute imports when necessary and prefer explicit relative imports for your local Django code.