Modules
Modules let you organize your Python code into reusable files. In Django, every app, view, model, and utility you write lives inside a module or package. Understanding how modules work helps you keep your project clean and maintainable.
What is a module?
A module is simply a .py
file that contains Python definitions — functions, classes, and variables — which can be imported and reused elsewhere in your project.
# math_utils.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b
You can now use this module anywhere in your Django project:
# views.py
from django.http import HttpResponse
from .math_utils import add
def index(request):
result = add(5, 3)
return HttpResponse(f"Result: {result}")
Packages and __init__.py
A package is a directory containing multiple related modules. Every package needs an __init__.py
file (can be empty) to tell Python “this folder is a package”.
# project structure example
myproject/
├── utils/
│ ├── __init__.py
│ ├── math_utils.py
│ └── string_utils.py
└── views.py
This structure allows you to import cleanly:
from utils.math_utils import add
from utils.string_utils import slugify_title
Absolute vs Relative Imports
Django projects often use absolute imports for clarity. Relative imports are shorter but can be confusing in large apps.
# Absolute import (recommended)
from myapp.utils.helpers import send_notification
# Relative import (works, but less clear)
from .utils.helpers import send_notification
Example: separating logic into modules
Suppose you have a Django app called blog
. You might organize it like this:
blog/
├── __init__.py
├── models.py
├── views.py
├── forms.py
├── utils/
│ ├── __init__.py
│ ├── text_tools.py
│ └── email_helpers.py
Each module handles a specific part of your app. This helps avoid circular imports and makes testing easier.
Dynamic Imports (Advanced)
Sometimes Django loads modules dynamically — for example, when you register apps or use importlib
to load signal handlers.
import importlib
utils = importlib.import_module("myapp.utils.text_tools")
print(utils.clean_html("<b>Hello</b>"))
Organizing Django utilities
You can keep all reusable helper functions inside a dedicated utils
package at your app or project level. For example:
# myproject/utils/email.py
from django.core.mail import send_mail
def notify_admin(subject, message):
send_mail(subject, message, "noreply@myproject.com", ["admin@myproject.com"])
Best practices for modules
- Group related logic together (e.g.
utils/
,services/
) - Keep each module small and focused
- Avoid circular imports — import lazily if needed
- Always include
__init__.py
in your packages - Use absolute imports for readability
Exercise
Create a new module utils/calculations.py
and move your add()
and subtract()
functions there. Then import and use them in your views.py
. Test that your Django server runs correctly and returns the expected result.
Next steps
Now that you understand functions and modules, you can organize your Django code efficiently. Next, explore how packages and apps work in Django — they’re Python modules with extra Django metadata.