Skip to main content

A modern, role-based Django CMS registry with rich media previews

Project description

django-var-cms

A modern, fully-customisable CMS registry for Django.
Think django-admin — but yours to control.


Quick Start

uv add django pillow whitenoise
uv run python manage.py migrate
uv run python manage.py seed_demo
uv run python manage.py runserver
# → http://127.0.0.1:8000/var-cms/

Demo accounts

Username Password Role Permissions
admin admin superuser Full access
editor editor editor Add + Edit (no delete)
author author author Add + limited field edits
viewer viewer viewer List + View only
alice alice viewer + delete override via UserPermission

Registration

Create var_cms_admin.py in any Django app — auto-discovered on startup.

from var_cms.registry    import var_cms_site, VarCMSModelAdmin
from var_cms.permissions import RolePermission, UserPermission

class ArticleAdmin(VarCMSModelAdmin):
    # ── List view ─────────────────────────────────────────────────────
    list_display  = ["title", "category__name", "author", "status", "created_at"]
    list_filter   = ["status", "category", "is_featured"]
    search_fields = ["title", "body", "author"]
    list_per_page = 25
    ordering      = ["-created_at"]

    # ── Form ──────────────────────────────────────────────────────────
    readonly_fields  = ["created_at", "updated_at", "view_count"]
    exclude_fields   = ["internal_notes"]

    # ── Role permissions ──────────────────────────────────────────────
    permissions = [
        RolePermission("superuser", add=True,  list=True, view=True, edit=True,  delete=True),
        RolePermission("editor",    add=True,  list=True, view=True, edit=True,  delete=False),
        RolePermission("author",    add=True,  list=True, view=True, edit=True,  delete=False),
        RolePermission("viewer",    add=False, list=True, view=True, edit=False, delete=False),
        UserPermission("alice",     add=True,  list=True, view=True, edit=True,  delete=True),
    ]

    # ── Per-role editable fields ──────────────────────────────────────
    role_editable_fields = {
        "superuser": "__all__",                          # everything
        "editor":    ["title", "body", "status", "category"],
        "author":    ["title", "body", "status"],        # can't touch slug/category
        "*":         [],                                  # all others: read-only
    }

var_cms_site.register(Article, ArticleAdmin)

Permissions

RolePermission — matched by Django group name or "superuser"

RolePermission("editor", add=True, list=True, view=True, edit=True, delete=False)

UserPermission — highest priority, matched by username

UserPermission("alice", add=True, list=True, view=True, edit=True, delete=True)

Overriding permission logic

class ArticleAdmin(VarCMSModelAdmin):
    def has_permission(self, request, action, obj=None):
        if action == "delete" and obj and obj.is_published:
            return False  # nobody can delete published articles
        return super().has_permission(request, action, obj)

Media Features

Image preview + Cropper

  • Click any image thumbnail to open the preview modal
  • Crop with free/fixed aspect ratio (1:1, 16:9, 4:3, etc.)
  • Rotate and flip
  • Export as JPEG, PNG, or WebP
  • Cropped file saved to MEDIA_ROOT/crops/

Video / Audio player

  • Native <video> and <audio> controls in the modal

PDF viewer

  • Inline <iframe> PDF preview

File conversion (API)

  • Images: JPEG ↔ PNG ↔ WebP ↔ BMP ↔ TIFF
  • Audio: MP3 ↔ WAV ↔ OGG ↔ FLAC ↔ AAC (requires ffmpeg)
  • Video: MP4 ↔ WebM ↔ AVI ↔ MOV (requires ffmpeg)
  • PDF→PNG: page-by-page (requires uv add pdf2image)
# Install ffmpeg (Linux)
sudo apt install ffmpeg

# PDF support
uv add pdf2image

Hooks

class ArticleAdmin(VarCMSModelAdmin):

    def get_queryset(self, request):
        return super().get_queryset(request).filter(site=request.site)

    def save_model(self, request, obj, form, change):
        if not change:
            obj.created_by = request.user
        obj.save()

    def delete_model(self, request, obj):
        obj.is_deleted = True   # soft delete
        obj.save()

Supported Field Types

Type List Filter Form
CharField / SlugField text text input
TextField ✓ truncated text textarea
IntegerField / Decimal min/max number
BooleanField ✓ icon yes/no checkbox
DateField / DateTimeField date range date picker
ForeignKey select select
choices select select
ImageField ✓ thumbnail + crop modal file
FileField ✓ preview link + modal file
PointField / PolygonField (GIS) ✓ geo badge WKT input

URL Structure

/var-cms/                          → Dashboard
/var-cms/{app}/{model}/            → List
/var-cms/{app}/{model}/add/        → Add form
/var-cms/{app}/{model}/{pk}/       → Edit form
/var-cms/{app}/{model}/{pk}/view/  → Detail view (read-only)
/var-cms/{app}/{model}/{pk}/delete/→ Delete confirm
/var-cms/api/media/crop/           → POST: crop image
/var-cms/api/media/convert/        → POST: convert file format

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_var_cms-1.0.1.tar.gz (745.5 kB view details)

Uploaded Source

Built Distribution

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

django_var_cms-1.0.1-py3-none-any.whl (757.6 kB view details)

Uploaded Python 3

File details

Details for the file django_var_cms-1.0.1.tar.gz.

File metadata

  • Download URL: django_var_cms-1.0.1.tar.gz
  • Upload date:
  • Size: 745.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.11

File hashes

Hashes for django_var_cms-1.0.1.tar.gz
Algorithm Hash digest
SHA256 82fe4be9404320a5875edcdf278fe48d1676d3fff706dfc1d830c974143f1f1f
MD5 c8ec6374516b888f6912ea5e2bf948ad
BLAKE2b-256 e3b2fdd65d732a3cf1b31db1f1cba8f698d531b39f77d0f2ce2bc75f8e66607a

See more details on using hashes here.

File details

Details for the file django_var_cms-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: django_var_cms-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 757.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.11

File hashes

Hashes for django_var_cms-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 c11b1c425820e39661236ee107417a0543eb40d90024e6a940a206e4cf49da06
MD5 e0c5994018180f2f425910118affe2f4
BLAKE2b-256 bebd13c3dc8c73772d37ccb21c3dc78d262378492864231605de519d38acfa50

See more details on using hashes here.

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