Packages
In Python, a package is a collection of related modules organized inside a folder that contains an __init__.py
file. Packages help structure larger Django projects and make your code reusable across multiple apps or even multiple projects.
What makes a package?
A directory becomes a Python package when it contains an __init__.py
file (even if it’s empty). This tells Python that the folder should be treated as a package that can be imported.
# folder structure
myproject/
├── blog/
│ ├── __init__.py
│ ├── models.py
│ ├── views.py
│ ├── utils/
│ │ ├── __init__.py
│ │ └── text_tools.py
│ └── urls.py
Now you can import modules like this:
from blog.utils.text_tools import clean_html
Django apps are packages
Every Django app (like auth
, admin
, or your own blog
app) is just a Python package. That’s why you can add it to INSTALLED_APPS
and import modules from it.
# settings.py
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"blog", # our package-based app
]
You can verify this by checking the folder structure inside Django’s source code — each app is a package with its own __init__.py
.
Using __init__.py
The __init__.py
file runs automatically when a package is imported. You can use it to control what gets imported, define shortcuts, or initialize settings.
# utils/__init__.py
from .text_tools import clean_html
__all__ = ["clean_html"]
Now you can do:
from utils import clean_html
Nested packages
Packages can contain other packages. This is common in Django when you have a large feature set that’s split by domain or functionality.
shop/
├── __init__.py
├── products/
│ ├── __init__.py
│ ├── models.py
│ └── views.py
├── orders/
│ ├── __init__.py
│ ├── models.py
│ └── views.py
└── utils/
├── __init__.py
└── payments.py
With this setup, you can cleanly import code from one part of the app to another:
from shop.utils.payments import process_payment
Creating reusable Django packages
If you want to share functionality across multiple Django projects (e.g., a custom authentication system, payment gateway, or utility library), you can convert your Django app into a reusable package.
Typical steps:
- Structure your app as a self-contained package
- Add a
setup.py
orpyproject.toml
file - Publish it to PyPI using
twine
Example: a reusable Django app django-cool-utils
might look like this:
django-cool-utils/
├── cool_utils/
│ ├── __init__.py
│ ├── models.py
│ ├── views.py
│ └── utils.py
├── README.md
└── pyproject.toml
Importing from installed packages
Once a package is installed (for example via pip install
), you can import it anywhere in your Django project.
import requests
from django.contrib.auth.models import User
Best practices
- Use packages to organize reusable and related modules
- Always include
__init__.py
to make folders importable - Prefer absolute imports to avoid confusion
- Use clear package names (avoid name clashes with built-in modules)
- When creating reusable apps, follow Django’s
AppConfig
pattern
Exercise
Create a new Django app called accounts
. Inside it, make a package helpers
containing emails.py
and tokens.py
. Import functions from these modules in your views.py
and test your imports.
Next steps
Now that you understand functions, modules, and packages, you’re ready to explore how Django’s project and app structure builds on top of these Python fundamentals. Next, you can dive into Django Apps & Project Architecture.