Getting Started
Ready after setup?
Once you have the basics installed, continue with Setup & Core CRUD basics for the full walkthrough. After you have seen the main features, read PowerCRUD Concepts to put the configuration model in perspective.
Installation
Install Python packages
Optional add-on:
- If you want saved favourites, also add the optional contrib app to
INSTALLED_APPS, run migrations, and mountpowercrud.urlswith namespacepowercrud. - The detailed behavior and UI guidance live in Saved Favourites.
Dependencies
Backend dependencies
Install django-powercrud and neapolitan via pip, then add the required Django apps and middleware in your settings.
PowerCRUD installs these Python dependencies automatically:
django-htmxdjango-template-partialsfor Django 5.2 template partial compatibilitypydantic
Backend library docs
- django-htmx: https://django-htmx.readthedocs.io/
- django-template-partials: https://github.com/carltongibson/django-template-partials
- pydantic: https://docs.pydantic.dev/latest/
Frontend dependencies
PowerCRUD ships package-owned frontend runtime assets and a packaged bundle.
Runtime responsibilities include:
- HTMX
- Tom Select (searchable single/multi select enhancement)
- Tippy.js (truncated-table tooltips/popovers)
- PowerCRUD runtime JS/CSS (
powercrud/js/powercrud.js,powercrud/css/powercrud.css)
You can run PowerCRUD in either of these modes:
- Bundled mode (recommended): load PowerCRUD's packaged Vite entry (
config/static/js/main.js). - Manual mode: install frontend dependencies yourself, then load PowerCRUD runtime assets from Django static paths.
Frontend library docs
- HTMX: https://htmx.org/docs/
- Tom Select: https://tom-select.js.org/
- Tippy.js: https://atomiks.github.io/tippyjs/
- daisyUI: https://daisyui.com/docs/
- Tailwind CSS: https://tailwindcss.com/docs
Projects that use the built-in templates but manage assets manually should read those docs. Projects that load the packaged bundle can usually ignore package-level frontend dependency wiring.
Required Configuration
Minimum required wiring for PowerCRUD
PowerCRUD depends on these Django integrations:
- Add to
INSTALLED_APPS:powercrud,neapolitan,django_htmx - On Django 5.2 only, also add
template_partials - Add to
MIDDLEWARE:django_htmx.middleware.HtmxMiddleware - Load the PowerCRUD frontend bundle in your base template, or provide equivalent frontend assets yourself
pydanticis installed automatically and needs no extra Django setup
If django_htmx.middleware.HtmxMiddleware is missing, HTMX requests will fail at runtime.
Add to your settings.py:
# Required settings
import django
POWERCRUD_COMPAT_APPS = []
if django.VERSION < (6, 0):
POWERCRUD_COMPAT_APPS.append("template_partials")
INSTALLED_APPS = [
...
"powercrud",
"neapolitan",
"django_htmx",
*POWERCRUD_COMPAT_APPS,
...
]
MIDDLEWARE = [
...,
"django_htmx.middleware.HtmxMiddleware",
...,
]
# Optional: POWERCRUD_SETTINGS overrides (all keys are optional and have defaults)
POWERCRUD_SETTINGS = {
"POWERCRUD_CSS_FRAMEWORK": "daisyui", # built-in default
}
If your own templates define partials and need to support both Django 5.2 and 6.0, load PowerCRUD's compatibility tag library:
{% load powercrud_partials %}
{% partialdef toolbar %}
...
{% endpartialdef toolbar %}
{% partial toolbar %}
Django 6.0 includes template partials in core, so do not add template_partials to INSTALLED_APPS on Django 6 projects.
If you want the optional saved favourites feature:
The URL prefix can be different, but the namespace must stay powercrud.
If you do not install that contrib app and mount its shared URLs, filtering still works normally and the favourites UI simply remains unavailable.
Frontend Integration
You can install PowerCRUD in two ways.
Use the packaged bundle to keep setup small and behaviour aligned with docs.
When using django-vite, configure a dedicated app entry for PowerCRUD:
# settings.py
from importlib import resources
POWERCRUD_ASSETS_DIR = resources.files("powercrud").joinpath("assets")
STATIC_URL = "/static/"
STATICFILES_DIRS = [
# your existing static dirs...
str(POWERCRUD_ASSETS_DIR),
]
DJANGO_VITE = {
"default": {
# Your project's own frontend bundle config
},
"powercrud": {
"dev_mode": False,
"static_url_prefix": "/static/",
"manifest_path": str(POWERCRUD_ASSETS_DIR / "manifest.json"),
},
}
Then load the bundle entry in your base template:
See sample/templates/sample/daisyUI/base.html for a complete Vite-based example.
If your page also loads your app's own bundle, both lines can coexist:
{% vite_asset 'src/config/static/js/main.js' %}
{% vite_asset 'config/static/js/main.js' app='powercrud' %}
Bundle mode checks:
- Generated PowerCRUD asset URLs should be absolute, for example
/static/django_assets/.... - Ensure global
STATIC_URLis absolute, for example"/static/". - If URLs appear relative (for example
static/django_assets/...resolving to/your/page/path/static/...), setstatic_url_prefixto"/static/". - Ensure
POWERCRUD_ASSETS_DIRis registered inSTATICFILES_DIRSso static lookup can finddjango_assets/powercrud-*.js|css.
Projects that do not use django.contrib.staticfiles are especially sensitive here: static_url_prefix and STATICFILES_DIRS become mandatory for reliable packaged-bundle resolution.
If you manage frontend dependencies yourself, you must:
- Load vendor dependencies (
HTMX,Tom Select,Tippy.js). - Expose them as browser globals.
- Load PowerCRUD runtime assets.
Template example:
{% load static %}
<link rel="stylesheet" href="{% static 'powercrud/css/powercrud.css' %}">
<script src=".../htmx.min.js"></script>
<link rel="stylesheet" href=".../tom-select.default.min.css">
<script src=".../tom-select.complete.min.js"></script>
<script src=".../tippy-bundle.umd.min.js"></script>
<script type="module" src="{% static 'powercrud/js/powercrud.js' %}"></script>
If your project uses a JS bundler (for example Vite/Webpack) for vendor packages, expose globals in your app entry:
import htmx from "htmx.org";
import TomSelect from "tom-select";
import removeButtonPlugin from "tom-select/dist/js/plugins/remove_button.js";
import "tom-select/dist/css/tom-select.css";
import tippy from "tippy.js";
import "tippy.js/dist/tippy.css";
window.htmx = htmx;
TomSelect.define("remove_button", removeButtonPlugin);
window.TomSelect = TomSelect;
window.tippy = tippy;
Then load PowerCRUD runtime assets in your base template:
{% load static %}
<link rel="stylesheet" href="{% static 'powercrud/css/powercrud.css' %}">
<script type="module" src="{% static 'powercrud/js/powercrud.js' %}"></script>
Manual mode requirements:
- Load vendor dependencies before the module entry at
powercrud/js/powercrud.js. - Load only the stable module entry; the browser follows PowerCRUD's internal module imports.
- Load Tom Select's vendor CSS before
powercrud/css/powercrud.cssso the package can override Tom Select with daisyUI semantic colors. - Register the Tom Select
remove_buttonplugin if you want multi-select remove buttons. - If you use built-in daisyUI templates without the packaged bundle, you must provide your own daisyUI/Tailwind CSS stack.
Do not load both integration modes on the same page:
- Use either the packaged bundle (
{% vite_asset 'config/static/js/main.js' app='powercrud' %}), or: - Manual vendor/runtime assets.
Quick browser verification for manual mode:
Boolean(window.initPowercrudSearchableSelects) // true
Boolean(window.TomSelect) // true
Boolean(window.htmx) // true
If fields have data-powercrud-searchable-select="true" but no Tom Select UI appears, the runtime script is not loaded or window.TomSelect is missing.
Important: If you compile Tailwind yourself, ensure Tailwind includes PowerCRUD classes in its build process. See the Styling guide for details.
Quick Start Tutorial
Basic Setup
Start with a basic CRUD view. For reference see neapolitan's docs.
from powercrud.mixins import PowerCRUDMixin
from neapolitan.views import CRUDView
from . import models
class ProjectCRUDView(PowerCRUDMixin, CRUDView):
model = models.Project
fields = ["name", "owner", "last_review", "status"]
base_template_path = "core/base.html"
Add to URLs
PowerCRUD’s UrlMixin (inherited from Neapolitan) exposes get_urls() so you do not have to hand-write the five CRUD routes. Pick the style that suits your project:
from django.urls import path, include
from neapolitan.views import Role
from .views import ProjectCRUDView
app_name = "my_app" # keep namespaces aligned with your include()
urlpatterns = []
urlpatterns += ProjectCRUDView.get_urls()
If you prefer the unpack pattern:
Need fewer routes (and therefore fewer action buttons)? Limit the registered roles:
Only the List and View endpoints (and their buttons) will render in that case. Finally, include the app URLs at the project level as usual:
# config/urls.py
from django.urls import include, path
urlpatterns = [
path("projects/", include("my_app.urls")),
]
Your First Enhanced View
Add some powercrud features:
class ProjectCRUDView(PowerCRUDMixin, CRUDView):
model = models.Project
base_template_path = "core/base.html"
# Basic field control
fields = ["name", "owner", "status", "created_date"]
properties = ["is_overdue"] # Include @property fields
# Enable modern features
use_htmx = True
use_modal = True
# Add filtering
filterset_fields = ["owner", "status", "created_date"]
# Enable pagination
paginate_by = 25
# Optional: namespace for URLs
namespace = "my_app"
That's it! You now have a fully-featured CRUD interface with filtering, pagination, modals, and HTMX support.
Next Steps
- Core configuration - Field control and basic settings
- HTMX & Modals - Interactive features
- Filtering - Advanced search and filter options
- Bulk operations - Edit multiple records at once