Django

Setting up Django to serve components.

This guide demonstrates how to set up a minimal Django application with Basic Components, showcasing:

  • JinjaX component integration
  • Tailwind CSS styling
  • Alpine.js interactivity
  • HTMX dynamic updates

Prerequisites

Before starting, ensure you have:

  • Python 3.8 or higher
  • UV
  • Node.js 16+ and npm 8+
  • A text editor or IDE

Project Structure

The source is in examples/django:

examples/django/
├── app.py                      # Single-file Django application
├── components                  # JinjaX components
│   └── ui
│       ├── button
│       │   └── Button.jinja
│       └── card
│           ├── Card.jinja
│           ├── CardContent.jinja
│           ├── CardDescription.jinja
│           ├── CardFooter.jinja
│           ├── CardHeader.jinja
│           └── CardTitle.jinja
├── package-lock.json
├── package.json                # npm config (Tailwind)
├── pyproject.toml              # python project config
├── static                      # Static assets
│   ├── dist
│   │   └── output.css         # Compiled Tailwind CSS
│   └── src
│       └── input.css          # Source Tailwind CSS
├── tailwind.config.js         # Tailwind config
├── templates                  # Jinja template dir
│   └── index.html
└── uv.lock

<!doctype html>
<html>
<head>
  <title>Example</title>
  <!-- Include the Alpine.js library -->
  <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.14.1/dist/cdn.min.js"></script>
  <!-- Include the TailwindCSS library -->
  <link href="/static/dist/output.css" rel="stylesheet"/>
  <!-- tailwind inter font -->
  <link rel="stylesheet" href="https://rsms.me/inter/inter.css"/>
  <!-- htmx -->
  <script src="https://unpkg.com/htmx.org@1.9.12"></script>
</head>
<body class="min-h-screen bg-white dark:bg-black text-black dark:text-white">

<div class="mt-40 flex justify-center justify-center w-full">

  <!-- Card component example -->
  <Card className="w-[350px] mb-4">
    <CardHeader className="pb-3">
      <CardTitle>Components!</CardTitle>
      <CardDescription className="max-w-lg text-balance leading-relaxed">
        Using components is fun.
      </CardDescription>
    </CardHeader>
    <CardContent>
      The button below is enabled with htmx. Click to update it.
    </CardContent>
    <CardFooter>
      <!-- use htmx -->
      <Button
        variant="outline"
        hx-get="/button"
        hx-trigger="click"
        hx-target="this"
        hx-swap="outerHTML">htmx is enabled</Button>
    </CardFooter>
  </Card>
</div>

</body>
</html>
"""
Django example application demonstrating:
- JinjaX component integration
- Static file serving for Tailwind CSS
- HTMX dynamic updates
- Component rendering
"""

from pathlib import Path
import django
from django.core.management import execute_from_command_line
from django.urls import path
from django.shortcuts import render
from django.conf import settings
from django.conf.urls.static import static
from django.core.wsgi import get_wsgi_application
from django.http import HttpResponse
from basic_components.utils.tailwind import tw
from basic_components.utils.jinjax import setup_component_catalog


import jinja2
import jinjax

# Only configure settings if they haven't been configured yet
if not settings.configured:
    # Configure Django settings
    BASE_DIR = Path(__file__).resolve().parent

    settings.configure(
        DEBUG=True,
        SECRET_KEY="insecure-key-for-demo",
        ROOT_URLCONF=__name__,
        MIDDLEWARE=[
            "django.middleware.security.SecurityMiddleware",
            "django.middleware.common.CommonMiddleware",
        ],
        INSTALLED_APPS=[
            "django.contrib.staticfiles",
        ],
        TEMPLATES=[
            {
                "BACKEND": "django.template.backends.jinja2.Jinja2",
                "DIRS": [BASE_DIR / "templates"],
                "APP_DIRS": True,
                "OPTIONS": {
                    "environment": f"{__name__}.environment",
                },
            }
        ],
        DATABASES={
            "default": {
                "ENGINE": "django.db.backends.sqlite3",
                "NAME": BASE_DIR / "db.sqlite3",
            }
        },
        STATIC_URL="static/",
        STATICFILES_DIRS=[
            BASE_DIR / "static",
        ],
    )
    django.setup()


# Configure JinjaX environment
def environment(**options):
    env = jinja2.Environment(**options)
    env.add_extension(jinjax.JinjaX)

    # Add cn to globals
    env.globals["cn"] = tw

    # Setup JinjaX catalog
    catalog = jinjax.Catalog(jinja_env=env)
    setup_component_catalog(catalog)

    return env


def get_catalog():
    return django.template.engines["jinja2"].env.globals["catalog"]


# Define views
def index(request):
    return render(request, "index.html")


def button(request):
    """Example endpoint demonstrating direct component rendering.
    Used by htmx for dynamic button updates.
    """
    catalog = get_catalog()
    return HttpResponse(
        catalog.render("Button", variant="destructive", _content="HTMX IS ENABLED!")
    )


# URL patterns
urlpatterns = [
    path("", index),
    path("button/", button, name="button"),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

# WSGI application
application = get_wsgi_application()

# Command line interface
if __name__ == "__main__":
    execute_from_command_line(["manage.py", "runserver", "0.0.0.0:10000"])

Setup Instructions

Install Dependencies

# Navigate to project directory
cd examples/django

# Install npm dependencies for Tailwind
npm install

# Build Tailwind CSS
npm run build

# Create and activate Python virtual environment
uv sync
source .venv/bin/activate

Run the Application

# Start Django server
python app.py

You should see:

Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

Django version 4.2.x, using settings None
Starting development server at http://0.0.0.0:10000/
Quit the server with CONTROL-C.

Enable Tailwind Watch Mode In a separate terminal:

npm run watch
This will automatically rebuild Tailwind CSS when you make changes to your components.

Verify Installation

  1. Open your browser to http://localhost:10000
  2. You should see the example page with:
    • Styled components using Tailwind CSS
    • Working htmx button that updates on click
    • Dark mode support

Example Page

Common Issues and Solutions

  1. Styles Not Updating

    • Ensure Tailwind watch process is running
    • Check that static/dist/output.css is being served
    • Verify static files configuration in app.py
    • Clear browser cache
  2. Components Not Found

    • Check component directory structure
    • Verify JinjaX catalog configuration
    • Ensure component names match file names
    • Check component file extensions (.jinja)
  3. Static Files 404

    • Verify STATICFILES_DIRS setting
    • Check static URL configuration
    • Ensure StaticMiddleware is enabled
  4. htmx Not Working

    • Check browser console for errors
    • Verify htmx script is loaded
    • Confirm URL patterns are correct
    • Check htmx attributes on components

Next Steps

  • Review the Components Guide to learn about available components
  • Explore Modern Tools to understand the tech stack
  • Check out the Examples for more usage patterns
  • Consider expanding to a full Django project structure for larger applications