Packages

FUNCTIONS AND MODULES


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:

  1. Structure your app as a self-contained package
  2. Add a setup.py or pyproject.toml file
  3. 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.