Skip to main content

MVP framework for Django - scaffold production-ready applications with sophisticated layouts and UI patterns designed for data-centric applications.

Project description

Django MVP

Tests Build Release PyPI codecov Python Versions Django Versions License: MIT

AdminLTE 4 for Django - A modern, responsive admin dashboard template system built with Django Cotton, providing AdminLTE 4 layouts and components for building production-ready data-centric applications.

Note: This project is currently in active development. Version 1.0 will introduce AdminLTE 4 integration with breaking changes from previous versions.

Overview

Django MVP brings the powerful AdminLTE 4 admin dashboard template to Django as a collection of reusable django-cotton components. It provides:

  • AdminLTE 4 Layout System - Full implementation of AdminLTE's grid-based layout structure
  • Configuration-Driven Design - Control layout and appearance via Django settings
  • Cotton Component Library - AdminLTE-specific components (cards, boxes, widgets, etc.)
  • Bootstrap 5 Foundation - Built on Bootstrap 5 with django-cotton-bs5 for base components
  • Production-Ready - Designed for data-centric applications, admin interfaces, and dashboards

What's Included

Django MVP provides AdminLTE-specific components only. Standard Bootstrap 5 components (buttons, modals, forms, etc.) are provided by the separate django-cotton-bs5 package. This includes:

  • AdminLTE Layouts - App wrapper, sidebar, header, main content area, footer
  • AdminLTE Widgets - Info boxes, small boxes, cards, direct chat
  • AdminLTE Components - Specialized components unique to AdminLTE
  • View Mixins - Python helpers for common patterns (search, ordering, pagination)
  • Menu Integration - Renderers for django-flex-menus

Architecture

Django MVP mirrors AdminLTE 4's grid-based layout structure:

.app-wrapper (grid container)
├── .app-sidebar (navigation)
├── .app-header (top navbar)
├── .app-main (content area)
│   ├── .app-content-header (page header/breadcrumbs)
│   └── .app-content (main content)
└── .app-footer (optional footer)

Installation

pip install django-mvp

Add required apps to INSTALLED_APPS in settings.py:

INSTALLED_APPS = [
    ...
    "django_cotton",      # Cotton template components
    "cotton_bs5",         # Bootstrap 5 components
    "easy_icons",         # Icon system
    "flex_menu",          # Optional: menu system
    "mvp",                # Django MVP
    ...
]

Add Context Processor

Add the MVP context processor to make configuration available in all templates:

TEMPLATES = [
    {
        ...
        "OPTIONS": {
            "context_processors": [
                ...
                "mvp.context_processors.mvp_config",
            ],
        },
    },
]

Configure Icons

Django MVP uses Bootstrap Icons via django-easy-icons:

EASY_ICONS = {
    "default": {
        "renderer": "easy_icons.renderers.ProviderRenderer",
        "config": {"tag": "i"},
        "icons": {
            # Core Actions
            "add": "bi bi-plus-circle",
            "create": "bi bi-plus-circle",
            "edit": "bi bi-pencil",
            "delete": "bi bi-trash",
            "save": "bi bi-floppy",
            "cancel": "bi bi-x-circle",
            "view": "bi bi-eye",
            # Navigation
            "arrow-right": "bi bi-arrow-right",
            "chevron_down": "bi bi-chevron-down",
            "chevron_up": "bi bi-chevron-up",
            "search": "bi bi-search",
            "filter": "bi bi-funnel",
            "person": "bi bi-person",
            "calendar": "bi bi-calendar3",
            "settings": "bi bi-gear",
            "theme_light": "bi bi-sun",
            "theme_dark": "bi bi-moon",
            "github": "bi bi-github",
        },
    },
}

Template Hierarchy

Django MVP follows a simple template hierarchy:

  1. base.html - Foundation HTML structure with AdminLTE CSS/JS
  2. mvp/base.html - AdminLTE app-wrapper layout structure
  3. Your templates - Extend mvp/base.html and override blocks

Example page template:

{% extends "mvp/base.html" %}

{% block content %}
  <div class="container-fluid">
    <h1>Your Page Content</h1>
  </div>
{% endblock %}

Customizing Layouts

Create a custom base layout in your project to override blocks:

{# templates/layouts/base.html in your project #}
{% extends "mvp/mvp/base.html" %}

{% block extra_css %}
  <link rel="stylesheet" href="{% static 'css/custom.css' %}">
{% endblock %}

Layout Configuration

Django MVP provides flexible layout control through the <c-app> component with boolean attributes for fixed positioning of sidebar, header, and footer elements.

Fixed Sidebar Layout

Make the sidebar sticky during vertical scrolling:

{% load cotton %}
<c-app fixed_sidebar>
    {% block content %}
        <h1>Dashboard</h1>
    {% endblock %}
</c-app>

Effect: Sidebar remains visible on the left while scrolling through content. Best for: Admin dashboards and data-centric applications.

Fixed Header Layout

Keep the navigation bar at the top:

<c-app fixed_header>
    {% block content %}
        <h1>Long Article</h1>
    {% endblock %}
</c-app>

Effect: Top navigation bar stays fixed at the top. Best for: Applications with important navigation or branding.

Fixed Footer Layout

Keep the footer visible at the bottom:

<c-app fixed_footer>
    {% block content %}
        <h1>Terms of Service</h1>
    {% endblock %}
</c-app>

Effect: Footer remains at the bottom while scrolling. Best for: Copyright notices or action buttons that should remain accessible.

Combining Fixed Elements

Multiple attributes can be used together:

<!-- Admin dashboard with fixed sidebar and header -->
<c-app fixed_sidebar fixed_header>
    {% block content %}
        <h1>Admin Panel</h1>
    {% endblock %}
</c-app>

<!-- Complete fixed layout (sidebar, header, footer) -->
<c-app fixed_sidebar fixed_header fixed_footer>
    {% block content %}
        <h1>Full Fixed Layout</h1>
    {% endblock %}
</c-app>

Responsive Sidebar Control

Control when the sidebar expands from mobile drawer to visible sidebar:

<!-- Sidebar expands on tablets and above (768px) -->
<c-app sidebar_expand="md">
    {% block content %}
        <h1>Mobile-Optimized App</h1>
    {% endblock %}
</c-app>

<!-- Sidebar expands on wide screens (1200px) -->
<c-app sidebar_expand="xl">
    {% block content %}
        <h1>Wide Layout App</h1>
    {% endblock %}
</c-app>

Available breakpoints: sm (576px), md (768px), lg (992px, default), xl (1200px), xxl (1400px)

Per-Page Layout Overrides

Different pages can use different layout configurations:

{# templates/dashboard.html - needs navigation visible #}
{% load cotton %}
<c-app fixed_sidebar fixed_header>
    <h1>Dashboard</h1>
</c-app>

{# templates/article.html - immersive reading experience #}
{% load cotton %}
<c-app>
    <h1>Article Title</h1>
    <p>Content...</p>
</c-app>

For complete layout documentation, see App Component Reference.

Navigation Menus

Django MVP provides a configurable navigation menu system using django-flex-menus with AdminLTE 4 sidebar styling. Menus are defined in Python and automatically rendered in the sidebar.

Basic Menu Setup

  1. Import and extend the default AppMenu in your app's menus.py file:
# myapp/menus.py
from flex_menu import MenuItem
from mvp.menus import AppMenu

# Add menu items to the global AppMenu
AppMenu.children.extend([
    MenuItem(
        name="dashboard",
        extra_context={
            "label": "Dashboard",
            "view_name": "dashboard",
            "icon": "speedometer2"
        }
    ),
    MenuItem(
        name="users",
        extra_context={
            "label": "User Management",
            "view_name": "user-list",
            "icon": "people",
            "badge": "12",
            "badge_classes": "text-bg-primary"
        }
    ),
])
  1. Import the menus in your app's apps.py:
# myapp/apps.py
from django.apps import AppConfig

class MyappConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'myapp'

    def ready(self):
        # Import menus to register them
        from . import menus

Hierarchical Menu Groups

Create organized menu sections with nested items:

# myapp/menus.py
from flex_menu import MenuItem
from mvp.menus import AppMenu

# Single menu items (appear at top)
AppMenu.children.extend([
    MenuItem(
        name="dashboard",
        extra_context={
            "label": "Dashboard",
            "view_name": "dashboard",
            "icon": "house"
        }
    ),
])

# Menu groups (appear after singles)
user_management = MenuItem(
    name="user_management",
    extra_context={
        "group_header": "User Management",  # Creates section header
        "icon": "people"
    },
    children=[
        MenuItem(
            name="user_list",
            extra_context={
                "label": "All Users",
                "view_name": "user-list",
                "icon": "person"
            }
        ),
        MenuItem(
            name="user_roles",
            extra_context={
                "label": "Roles & Permissions",
                "view_name": "user-roles",
                "icon": "shield"
            }
        ),
    ]
)

AppMenu.children.append(user_management)

Menu Features

Single Menu Items: Direct links that appear at the top of the sidebar

  • label: Display text
  • view_name: Django URL name for reverse() lookup
  • icon: Bootstrap icon name (via django-easy-icons)
  • badge: Optional badge text
  • badge_classes: CSS classes for badge styling

Menu Groups: Collapsible sections with headers and nested items

  • group_header: Section header text
  • children: List of child MenuItem objects
  • Automatically uses nav-treeview and menu-open classes

Active State Detection: Automatically highlights current page menu items based on URL matching.

Icon Configuration

Menu icons use django-easy-icons with Bootstrap Icons. Configure available icons in settings.py:

EASY_ICONS = {
    "default": {
        "renderer": "easy_icons.renderers.ProviderRenderer",
        "config": {"tag": "i"},
        "icons": {
            "house": "bi bi-house",
            "people": "bi bi-people",
            "person": "bi bi-person",
            "shield": "bi bi-shield",
            "gear": "bi bi-gear",
            "speedometer2": "bi bi-speedometer2",
        },
    },
}

Cotton Components (Optional)

For custom menu implementations, use the included Cotton components:

{% load cotton %}

{# Complete menu structure #}
<c-app.sidebar.menu>
    <c-app.sidebar.menu.group label="MAIN NAVIGATION">
        <c-app.sidebar.menu.item label="Dashboard" href="/" icon="house" active=True />
        <c-app.sidebar.menu.item label="Users" icon="people" badge="5">
            <c-app.sidebar.menu.item label="All Users" href="/users/" />
            <c-app.sidebar.menu.item label="Add User" href="/users/add/" />
        </c-app.sidebar.menu.item>
    </c-app.sidebar.menu.group>
</c-app.sidebar.menu>

For detailed menu system documentation, see Navigation Guide.

Quick Start

Basic Page Template

{% extends "mvp/base.html" %}

{% block content %}
  <div class="app-content">
    <div class="container-fluid">
      <h1>Welcome to My Application</h1>
      <p>Your content here...</p>
    </div>
  </div>
{% endblock %}

With Page Header and Breadcrumbs

{% extends "mvp/base.html" %}

{% block page_header %}
  <div class="app-content-header">
    <div class="container-fluid">
      <div class="row">
        <div class="col-sm-6">
          <h3 class="mb-0">Dashboard</h3>
        </div>
        <div class="col-sm-6">
          <ol class="breadcrumb float-sm-end">
            <li class="breadcrumb-item"><a href="/">Home</a></li>
            <li class="breadcrumb-item active">Dashboard</li>
          </ol>
        </div>
      </div>
    </div>
  </div>
{% endblock %}

{% block content %}
  <div class="app-content">
    <div class="container-fluid">
      <!-- Your dashboard content -->
    </div>
  </div>
{% endblock %}

AdminLTE Components

Django MVP provides Cotton components for AdminLTE-specific widgets. Standard Bootstrap components (buttons, modals, forms, etc.) should use django-cotton-bs5.

Available Components:

  • Info Box - Display metrics with icons and optional progress bars
  • Small Box - Prominent dashboard summary widgets with action links
  • Card - Flexible content containers with collapsible sections

Info Box

Display key metrics with icons and optional progress indicators:

<c-info-box
  icon="box-seam"
  text="New Orders"
  number="150"
  variant="primary" />

<!-- With progress bar -->
<c-info-box
  icon="add"
  text="Downloads"
  number="114,381"
  variant="info"
  progress="70"
  description="70% Increase in 30 Days" />

<!-- Box fill mode (entire box colored) -->
<c-info-box
  icon="briefcase"
  text="Sales"
  number="13,648"
  variant="success"
  fill="box" />

Small Box

Create prominent summary cards for dashboard overviews:

<c-small-box
  heading="150"
  text="New Orders"
  icon="cart"
  variant="success" />

<!-- With action link -->
<c-small-box
  heading="53%"
  text="Bounce Rate"
  icon="chart"
  variant="warning"
  link="/stats/"
  link_text="View details" />

Card

Build flexible content containers with headers, bodies, and footers:

<!-- Basic card -->
<c-card title="Monthly Report" variant="primary">
  Card content here
</c-card>

<!-- With icon and tools -->
<c-card title="Revenue" icon="chart" variant="success" fill="header">
  <c-slot name="tools">
    <button type="button" class="btn btn-tool" data-lte-toggle="card-collapse">
      <c-icon name="dash" />
    </button>
  </c-slot>

  Revenue details and charts...

  <c-slot name="footer">
    Last updated: January 2026
  </c-slot>
</c-card>

<!-- Collapsible card -->
<c-card title="Options" collapsed>
  <c-slot name="tools">
    <button type="button" class="btn btn-tool" data-lte-toggle="card-collapse">
      <c-icon name="plus" />
    </button>
  </c-slot>

  Expandable content...
</c-card>

Fill Modes for Cards:

  • fill="outline" (default) - Colored border only
  • fill="header" - Colored header background
  • fill="card" - Entire card colored

See the component documentation for complete API references, examples, and accessibility guidelines.

Navbar Widgets

Django MVP provides interactive navbar widgets for common application features:

Add widgets to the navbar via the navbar_right block:

{% extends "mvp/base.html" %}

{% block navbar_right %}
  {# Fullscreen toggle #}
  <c-navbar.fullscreen-widget />

  {# Theme switcher #}
  <c-navbar.theme-switcher-widget />

  {# Messages #}
  <c-navbar.messages-widget
    unread_count="3"
    messages=messages />

  {# Notifications #}
  <c-navbar.notifications-widget
    unread_count="5"
    notifications=notifications />

  {# User profile #}
  <c-navbar.user-profile-widget
    user=request.user
    avatar_url=user.profile.avatar_url
    member_since="Jan 2024" />
{% endblock %}

Custom Widget Example:

{# templates/navbar_widgets/tasks_widget.html #}
<c-navbar.custom-widget
  icon="check2-square"
  dropdown_id="tasks-dropdown"
  badge_count="{{ tasks_count }}"
  badge_color="danger">

  <c-slot name="children">
    {% for task in tasks %}
      <a href="{{ task.get_absolute_url }}" class="dropdown-item">
        <i class="bi bi-circle{{ task.is_complete|yesno:'-fill,,' }}"></i>
        {{ task.title }}
        <span class="float-end text-muted text-sm">{{ task.due_date|timesince }}</span>
      </a>
    {% endfor %}

    <div class="dropdown-divider"></div>
    <a href="{% url 'tasks:list' %}" class="dropdown-item dropdown-footer">
      See All Tasks
    </a>
  </c-slot>
</c-navbar.custom-widget>

See the navbar widgets documentation and custom widget tutorial for complete API references, usage patterns, and accessibility guidelines.

View Mixins

Python mixins for common patterns:

SearchMixin

Django admin-style multi-field search:

from mvp.views import SearchMixin
from django.views.generic import ListView

class ProjectListView(SearchMixin, ListView):
    model = Project
    search_fields = ["title", "description", "owner__username"]

OrderMixin

Dropdown-based result ordering:

from mvp.views import OrderMixin
from django.views.generic import ListView

class ProjectListView(OrderMixin, ListView):
    model = Project
    order_fields = {
        "title": "Title A-Z",
        "-title": "Title Z-A",
        "-created": "Newest First",
        "created": "Oldest First",
    }

Form View Mixins

MVPFormView provides automatic form renderer detection and AdminLTE card layout for forms. It intelligently detects django-crispy-forms, django-formset, or falls back to Django's standard rendering.

Basic Form View:

from mvp.views import MVPFormView
from myapp.forms import ContactForm

class ContactFormView(MVPFormView):
    form_class = ContactForm
    success_url = "/contact/success/"
    page_title = "Contact Us"

Create View (Model Forms):

from mvp.views import MVPCreateView
from myapp.models import Product

class ProductCreateView(MVPCreateView):
    model = Product
    fields = ["name", "slug", "category", "description", "price", "stock"]
    success_url = "/products/"
    page_title = "Add New Product"

Update View (Edit Forms):

from mvp.views import MVPUpdateView
from myapp.models import Product

class ProductUpdateView(MVPUpdateView):
    model = Product
    fields = ["name", "slug", "category", "description", "price", "stock"]
    success_url = "/products/"
    page_title = "Edit Product"

Explicit Renderer Override:

class ContactFormView(MVPFormView):
    form_class = ContactForm
    success_url = "/contact/success/"
    page_title = "Contact Us"
    form_renderer = "crispy"  # Override auto-detection: "crispy", "formset", or "django"

Renderer Detection Priority:

  1. form_renderer attribute (if set)
  2. django-crispy-forms (if installed)
  3. django-formset (if installed)
  4. Django standard form rendering (fallback)

All form views automatically use AdminLTE card layout with consistent styling, CSRF protection, and responsive design.

Requirements

  • Python 3.12 or 3.13
  • Django 5.2 or 6.0 (currently supported Django releases)
  • django-cotton 2.3.1+
  • django-cotton-bs5 0.9.0+
  • django-easy-icons 0.5+
  • AdminLTE 4.x (CSS/JS included)

Design Philosophy

Django MVP provides:

  1. AdminLTE Layout System - Grid-based app-wrapper structure
  2. Configuration-Driven - Control via Django settings, not templates
  3. AdminLTE Components Only - Standard BS5 components in django-cotton-bs5
  4. Production-Ready - Built for data-centric dashboards and admin interfaces

Use Cases

Ideal for:

  • Admin dashboards with metrics and data visualization
  • Data management applications requiring sophisticated layouts
  • Internal tools with complex navigation structures
  • Research portals managing datasets and projects
  • SaaS admin interfaces with multi-tenant support

Contributing

Contributions welcome! When adding components:

  1. Focus on AdminLTE-specific components only
  2. Use <c-vars /> for default values
  3. Include proper ARIA attributes
  4. Support AdminLTE's data attributes and JS interactions
  5. Add tests for new components

Theming & Vendor SCSS

Django MVP compiles its styles through django-compressor and django-libsass. The AdminLTE 4 SCSS sources are vendored into mvp/static/adminlte/scss/.

Customize Theme Variables

There are two override files — use whichever fits the variable you need:

mvp/static/_bootstrap_variables.scss — Bootstrap design tokens and plain AdminLTE values:

// mvp/static/_bootstrap_variables.scss
$primary:   #2c5f2e;
$secondary: #606c38;

mvp/static/_adminlte_variables.scss — AdminLTE variables that reference Bootstrap tokens:

// mvp/static/_adminlte_variables.scss
$lte-sidebar-color: $primary;  // can safely reference Bootstrap vars here

All overrides in _bootstrap_variables.scss are imported before the vendor defaults, so any variable you define takes precedence over Bootstrap and AdminLTE's !default values. Overrides in _adminlte_variables.scss are injected after Bootstrap vars are resolved.

To provide app-specific overrides, create the same-named file in your app's static root and list your app before mvp in INSTALLED_APPS (same pattern as Django template overrides).

Refresh the Vendored SCSS Tree

When a new AdminLTE version is available, run:

invoke refresh-adminlte-scss

This will:

  1. Install the latest AdminLTE 4 package with npm (admin-lte@^4).
  2. Delete the current vendored SCSS tree in full (preventing stale files).
  3. Copy the refreshed SCSS sources into mvp/static/adminlte/scss/.
  4. Patch adminlte.scss to inject the _adminlte_variables override hook.

After the refresh, commit package-lock.json to pin the resolved version for deterministic builds on CI and other machines.

Full docs: See specs/018-vendor-adminlte-scss/quickstart.md for detailed override guidance, troubleshooting steps, and first-time timing protocols.

License

MIT License - see LICENSE file for details.

Acknowledgments

Built with:

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_mvp-0.12.0.tar.gz (114.6 kB view details)

Uploaded Source

Built Distribution

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

django_mvp-0.12.0-py3-none-any.whl (144.4 kB view details)

Uploaded Python 3

File details

Details for the file django_mvp-0.12.0.tar.gz.

File metadata

  • Download URL: django_mvp-0.12.0.tar.gz
  • Upload date:
  • Size: 114.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for django_mvp-0.12.0.tar.gz
Algorithm Hash digest
SHA256 a51790e87c827b9afa4a4a55caac26c00d9564537eacd73c787f5384376bf6a8
MD5 a5310b30e93bd0ac586dc5cc36b602d3
BLAKE2b-256 f9a00d0e250e77c14e9f19642922c6293566274a5c966f96719711e0fd0512f4

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_mvp-0.12.0.tar.gz:

Publisher: on-release-main.yml on django-mvp/django-mvp

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_mvp-0.12.0-py3-none-any.whl.

File metadata

  • Download URL: django_mvp-0.12.0-py3-none-any.whl
  • Upload date:
  • Size: 144.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for django_mvp-0.12.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ac7dfe14dbdc2f2c6ba932104de6127a0172ee74f697bfc8a2af3054eebedf8f
MD5 778ac09a530c34ae00d2daaa124283c5
BLAKE2b-256 0375d0c6d1d5e3f36e4550762aba8e6c44375522806504c2c4bcac871f6dca6c

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_mvp-0.12.0-py3-none-any.whl:

Publisher: on-release-main.yml on django-mvp/django-mvp

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