Skip to main content

Declaratively setup Django before deployment in any environment

Project description

Django Setup Tools

Python Version Django Version codecov GitHub GitHub last commit

Django Setup Tools is a Django package that enables declarative configuration of setup scripts for Django applications. It provides a simple way to run initialization scripts and ongoing maintenance tasks in different environments during deployment.

What It Does

Django Setup Tools allows you to:

  • Run initialization scripts only when the database is first set up
  • Execute maintenance tasks every time the setup command runs
  • Configure different behaviors for different environments (development, staging, production)
  • Mix Django management commands with custom Python functions
  • Ensure consistent deployment across different environments

Key Features

  • 🚀 Environment-specific configurations - Different scripts for dev, staging, production
  • 🔄 One-time and recurring scripts - Scripts that run only on initial setup vs. every deployment
  • 🛠 Flexible command types - Support for Django management commands and custom Python functions
  • 🎯 Simple configuration - Just add settings to your Django configuration
  • 🧪 Well-tested - Comprehensive test suite with high coverage
  • 📝 Type-safe - Full type hints for better IDE support

Installation

Using pip

pip install django-setup-tools

Using Poetry

poetry add django-setup-tools

Django Configuration

Add django_setup_tools to your INSTALLED_APPS in settings.py:

INSTALLED_APPS = [
    # ... your other apps
    'django_setup_tools',
]

Quick Start

1. Basic Configuration

Add the setup configuration to your Django settings:

# settings.py
DJANGO_SETUP_TOOLS = {
    "": {  # Default configuration (applies to all environments)
        "on_initial": [
            # These run only when the database is first initialized
            ("makemigrations", "--no-input"),
            ("migrate", "--no-input"),
            ("createsuperuser", "--no-input", "--username=admin", "--email=admin@example.com"),
        ],
        "always_run": [
            # These run every time the setup command is executed
            ("migrate", "--no-input"),
            "django_setup_tools.scripts.sync_site_id",  # Custom function
        ],
    }
}

# Required for sync_site_id script
SITE_ID = 1
SITE_DOMAIN = "your-domain.com"
SITE_NAME = "Your Site Name"

2. Run the Setup Command

python manage.py setup

This will:

  • Check if the database is initialized
  • Run on_initial scripts if it's the first time
  • Always run always_run scripts

Environment-Specific Configuration

You can configure different behaviors for different environments:

# settings.py
DJANGO_SETUP_TOOLS_ENV = "development"  # or "staging", "production", etc.

DJANGO_SETUP_TOOLS = {
    "": {  # Default configuration
        "on_initial": [
            ("makemigrations", "--no-input"),
            ("migrate", "--no-input"),
        ],
        "always_run": [
            ("migrate", "--no-input"),
        ],
    },
    "development": {  # Development-specific
        "on_initial": [
            ("loaddata", "dev_fixtures.json"),
        ],
        "always_run": [
            ("collectstatic", "--no-input"),
        ],
    },
    "production": {  # Production-specific
        "on_initial": [
            ("createsuperuser", "--no-input", "--username=admin"),
        ],
        "always_run": [
            ("collectstatic", "--no-input"),
            ("compress", "--force"),
        ],
    },
}

Command Types

Django Management Commands

You can specify Django management commands in three formats:

DJANGO_SETUP_TOOLS = {
    "": {
        "always_run": [
            "migrate",  # Simple command
            ("migrate", "--no-input"),  # Command with arguments (tuple)
            ["loaddata", "fixtures.json"],  # Command with arguments (list)
        ],
    }
}

Custom Python Functions

You can also call custom Python functions:

# myapp/scripts.py
def my_custom_setup(handler, *args):
    """Custom setup function."""
    handler.stdout.write("Running custom setup...")
    # Your custom logic here
    handler.stdout.write("Custom setup completed!")

# settings.py
DJANGO_SETUP_TOOLS = {
    "": {
        "always_run": [
            "myapp.scripts.my_custom_setup",
            ("myapp.scripts.my_custom_setup", "arg1", "arg2"),  # With arguments
        ],
    }
}

Custom functions receive:

  • handler: The management command instance (for output and styling)
  • *args: Any additional arguments specified in the configuration

Built-in Scripts

Django Setup Tools includes many useful built-in scripts for common deployment and maintenance tasks:

Site Management

sync_site_id

Synchronizes the Django Site object with your settings:

# settings.py
SITE_ID = 1
SITE_DOMAIN = "yoursite.com"
SITE_NAME = "Your Site"

DJANGO_SETUP_TOOLS = {
    "": {
        "always_run": [
            "django_setup_tools.scripts.sync_site_id",
        ],
    }
}

Cache Management

clear_cache

Clears all Django cache backends:

DJANGO_SETUP_TOOLS = {
    "": {
        "always_run": [
            "django_setup_tools.scripts.clear_cache",
        ],
    }
}

Database Health

check_database_connection

Verifies database connectivity and reports basic information:

DJANGO_SETUP_TOOLS = {
    "": {
        "on_initial": [
            "django_setup_tools.scripts.check_database_connection",
        ],
    }
}

User Management

Django provides built-in support for creating superusers from environment variables. Simply use Django's built-in createsuperuser command with the --no-input flag:

# Set environment variables
export DJANGO_SUPERUSER_USERNAME=admin
export DJANGO_SUPERUSER_EMAIL=admin@yoursite.com
export DJANGO_SUPERUSER_PASSWORD=secure_password
DJANGO_SETUP_TOOLS = {
    "": {
        "on_initial": [
            ("createsuperuser", "--no-input"),  # Uses environment variables automatically
        ],
    }
}

Django automatically looks for these environment variables:

  • DJANGO_SUPERUSER_USERNAME
  • DJANGO_SUPERUSER_EMAIL
  • DJANGO_SUPERUSER_PASSWORD

Configuration Validation

verify_environment_config

Checks for required environment variables and Django settings:

DJANGO_SETUP_TOOLS = {
    "": {
        "always_run": [
            "django_setup_tools.scripts.verify_environment_config",
        ],
    }
}

check_static_files_config

Verifies static files configuration (STATIC_URL, STATIC_ROOT, etc.):

DJANGO_SETUP_TOOLS = {
    "": {
        "on_initial": [
            "django_setup_tools.scripts.check_static_files_config",
        ],
    }
}

Logging Setup

setup_log_directories

Creates log directories based on your Django logging configuration:

DJANGO_SETUP_TOOLS = {
    "": {
        "on_initial": [
            "django_setup_tools.scripts.setup_log_directories",
        ],
    }
}

Complete Example with Multiple Scripts

Here's a comprehensive example using multiple built-in scripts:

DJANGO_SETUP_TOOLS = {
    "": {
        "on_initial": [
            "django_setup_tools.scripts.check_database_connection",
            "django_setup_tools.scripts.setup_log_directories",
            ("createsuperuser", "--no-input"),  # Uses environment variables automatically
            ("makemigrations", "--no-input"),
            ("migrate", "--no-input"),
            "django_setup_tools.scripts.sync_site_id",
        ],
        "always_run": [
            "django_setup_tools.scripts.verify_environment_config",
            "django_setup_tools.scripts.check_static_files_config",
            ("migrate", "--no-input"),
            ("collectstatic", "--no-input"),
            "django_setup_tools.scripts.clear_cache",
        ],
    }
}

Advanced Usage

Error Handling

The setup command will stop execution if any script fails. You can see detailed error messages in the output.

Database Initialization Detection

The command automatically detects if the database has been initialized by checking for the Django migrations table. This ensures on_initial scripts only run once.

Custom Script Best Practices

When writing custom scripts:

def my_script(handler, *args):
    """
    Example custom script with best practices.

    Args:
        handler: Django management command instance
        *args: Additional arguments
    """
    # Use handler for output with proper styling
    handler.stdout.write(
        handler.style.NOTICE("Starting custom script...")
    )

    try:
        # Your logic here
        result = do_something()

        handler.stdout.write(
            handler.style.SUCCESS(f"Script completed: {result}")
        )
    except Exception as e:
        handler.stdout.write(
            handler.style.ERROR(f"Script failed: {e}")
        )
        raise  # Re-raise to stop execution

Running Tests

Install Development Dependencies

# Using Poetry
poetry install

# Or using pip
pip install -r requirements-dev.txt

Run Tests

# Run all tests
pytest

# Run with coverage
pytest --cov=django_setup_tools

# Run specific test file
pytest tests/test_setup_command.py

# Run with verbose output
pytest -v

Test Structure

tests/
├── conftest.py                    # Pytest configuration
├── test_setup_command.py          # Original setup command tests
├── test_setup_command_extended.py # Extended setup command tests
├── test_scripts.py               # Tests for built-in scripts
└── test_integration.py           # Integration tests

Development

Setting Up Development Environment

# Clone the repository
git clone https://github.com/your-username/django-setup-tools.git
cd django-setup-tools

# Install with Poetry
poetry install

# Or create virtual environment and install with pip
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
pip install -e .
pip install -r requirements-dev.txt

Code Quality

The project uses several tools for code quality:

# Format code
black .

# Check types
mypy src/

# Lint code
pylint src/

# Check imports
isort --check-only .

# Run all checks
tox

Configuration Reference

Settings

Setting Type Default Description
DJANGO_SETUP_TOOLS dict {} Main configuration dictionary
DJANGO_SETUP_TOOLS_ENV str "" Environment name for environment-specific configs
SITE_ID int Required for sync_site_id Django site ID
SITE_DOMAIN str Required for sync_site_id Site domain name
SITE_NAME str Required for sync_site_id Site display name

Configuration Structure

DJANGO_SETUP_TOOLS = {
    "environment_name": {  # Use "" for default
        "on_initial": [
            # Commands that run only on first database initialization
        ],
        "always_run": [
            # Commands that run every time
        ],
    },
}

Examples

Development Environment

# settings/development.py
DJANGO_SETUP_TOOLS_ENV = "development"

DJANGO_SETUP_TOOLS = {
    "": {
        "on_initial": [
            ("makemigrations", "--no-input"),
            ("migrate", "--no-input"),
        ],
        "always_run": [
            ("migrate", "--no-input"),
        ],
    },
    "development": {
        "on_initial": [
            ("loaddata", "dev_users.json"),
            ("loaddata", "dev_data.json"),
        ],
        "always_run": [
            "django_setup_tools.scripts.sync_site_id",
        ],
    },
}

Production Environment

# settings/production.py
DJANGO_SETUP_TOOLS_ENV = "production"

DJANGO_SETUP_TOOLS = {
    "": {
        "on_initial": [
            ("migrate", "--no-input"),
        ],
        "always_run": [
            ("migrate", "--no-input"),
        ],
    },
    "production": {
        "on_initial": [
            ("createsuperuser", "--no-input", "--username=admin"),
        ],
        "always_run": [
            ("collectstatic", "--no-input", "--clear"),
            ("compress", "--force"),
            "django_setup_tools.scripts.sync_site_id",
            "myapp.deployment.clear_cache",
        ],
    },
}

Troubleshooting

Common Issues

Q: Scripts are running every time instead of just on initial setup A: Check that your database is properly configured and migrations table exists. The on_initial detection relies on Django's migration system.

Q: Custom function not found A: Ensure the function path is correct and the module is importable. Use the full dotted path like myapp.scripts.my_function.

Q: Commands failing with strange errors A: Check that all required Django apps are in INSTALLED_APPS and that the database is accessible.

Debug Mode

Enable debug output by setting Django's logging level:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django_setup_tools': {
            'handlers': ['console'],
            'level': 'DEBUG',
        },
    },
}

Contributing

We welcome contributions! Please see our Contributing Guide for details.

Reporting Issues

Please report issues on GitHub Issues.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Changelog

See CHANGELOG.md for version history.

Credits

  • Created by Sam Jennings
  • Inspired by the need for declarative Django deployment scripts
  • Built with ❤️ for the Django community

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_setup_tools-0.2.5.tar.gz (13.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_setup_tools-0.2.5-py3-none-any.whl (11.6 kB view details)

Uploaded Python 3

File details

Details for the file django_setup_tools-0.2.5.tar.gz.

File metadata

  • Download URL: django_setup_tools-0.2.5.tar.gz
  • Upload date:
  • Size: 13.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for django_setup_tools-0.2.5.tar.gz
Algorithm Hash digest
SHA256 ee77b83aae4578b60cd6902beef488ff831418b62276f45a998c571ff24e084b
MD5 ae13773a4e392cdec017d8ad7c121f9f
BLAKE2b-256 34dc6ad7b5e79dd0f3fca223e4528c9a4741733c5bf38224957daa41b30e9c49

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_setup_tools-0.2.5.tar.gz:

Publisher: on-release-main.yml on SamuelJennings/django-setup-tools

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_setup_tools-0.2.5-py3-none-any.whl.

File metadata

File hashes

Hashes for django_setup_tools-0.2.5-py3-none-any.whl
Algorithm Hash digest
SHA256 3158b6f846ff16a82128b5272bb63a4f178aa72529ef9df4261ad14fb24d67f3
MD5 26494a0c0d4891c218ad98097ba2950a
BLAKE2b-256 a1f442c55e9aefbda56f4e2f02b15140692fb7adc649c3b4b409fff17770baf6

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_setup_tools-0.2.5-py3-none-any.whl:

Publisher: on-release-main.yml on SamuelJennings/django-setup-tools

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page