Agent skill

Dj Models

by dvf in dvf/opinionated-django

Structure Django models with proper Meta classes, verbose names, and optimized indexes.

MITAuto-check: notesBackend & APIs

Install Dj Models

skills CLI
$ npx skills add dvf/opinionated-django --skill dj-models -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install dvf/opinionated-django dj-models --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/dvf/opinionated-django.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/dj-models .claude/skills/dj-models && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
dj-models
GitHub stars
109
Token cost
~4.9k tokens
SKILL.md length
1,473 words
Files
1
Skills in repo
9
Repo updated
First seen
Licence
MIT

At a glance

Structure Django models with proper Meta classes, verbose names, and optimized indexes.

  • Works in 4 steps: verbose_name and verbose_name_plural → indexes → constraints (unique constraints, check… → …
  • Reviewing Django models to ensure consistent ordering
  • SKILL.md covers BEFORE WRITING CODE, Model Structure, Rules and Admin Registration, plus 3 more sections
  • Calls uv

What it does

Dj Models is an agent skill from dvf/opinionated-django. Structure Django models with proper Meta classes, verbose names, and optimized indexes. Use when creating or reviewing Django models to ensure consistent ordering, correct verbosename/verbosenameplural, and database indexes aligned to actual query patterns. Also registers every model in the admin with a clean, fast-loading configuration.

Its SKILL.md is about 4.9k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Backend & APIs, covering Backend development. It works with Django. The repository describes itself as: An opinionated Django project with Repository pattern, Pydantic DTOs, svcs DI, and Stripe-style ULID IDs. The licence is MIT.

When your agent uses it

  • Reviewing Django models to ensure consistent ordering
  • Correct verbosename/verbosenameplural
  • Database indexes aligned to actual query patterns

Example prompts

  • “/dj-models”

Requirements

  • Python 3
  • Pre-approved tools (allowed-tools): Read, Write, Edit, Bash, Grep, Glob

Workflow steps

4 steps, taken from the first numbered list in SKILL.md.

  1. verbose_name and verbose_name_plural
  2. indexes
  3. constraints (unique constraints, check constraints)
  4. Anything else (ordering, abstract, etc.)

What it can do on your machine

Read from SKILL.md and the folder at commit f17fc2d. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves these tools, so the agent can use them without asking each time:

    • Read
    • Write
    • Edit
    • Bash
    • Grep
    • Glob

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • uv

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use uv, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Dj Models loads about 4.9k tokens when it runs. Until then it costs about 88 tokens; SKILL.md has 1,473 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~88
When it runs · the whole SKILL.md, loaded when a task matches
~4.9k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check: notes

The automated check noted patterns worth knowing about, such as sudo or a known installer.

  • NotePre-approves every shell command (allowed-tools: Bash)SKILL.md
    allowed-tools: Read, Write, Edit, Bash, Grep, Glob

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from dvf/opinionated-django at commit f17fc2d, republished under its MIT licence (© dvf). 1,473 words, ~4,866 tokens.

Download SKILL.mdSave it as .claude/skills/dj-models/SKILL.md (or your agent's skills folder).
name
dj-models
description
Structure Django models with proper Meta classes, verbose names, and optimized indexes. Use when creating or reviewing Django models to ensure consistent ordering, correct verbose_name/verbose_name_plural, and database indexes aligned to actual query patterns. Also registers every model in the admin with a clean, fast-loading configuration.
allowed-tools
Read, Write, Edit, Bash, Grep, Glob

Structure a Django Model

You are defining or restructuring a Django model in an opinionated, fully type-safe Django project. Every convention below is mandatory. Do not deviate.

BEFORE WRITING CODE

Read the model file being created or modified, plus:

  • src/project/ids.py — existing ID prefixes
  • Any existing models in the same app — for cross-model index considerations
  • The repository that queries this model — to understand real query patterns
  • src/<app>/admin.py — existing admin registrations

Model Structure

Every model follows this exact ordering of members:

python
from typing import ClassVar

from django.db import models

from project.ids import generate_xxx_id


class MyEntity(models.Model):
    # 1. Meta — ALWAYS first, before any field
    class Meta:
        verbose_name = "my entity"
        verbose_name_plural = "my entities"
        indexes = [
            models.Index(fields=["-created_at"], name="idx_%(class)s_recent"),
        ]
        constraints = [
            models.UniqueConstraint(fields=["slug"], name="uq_%(class)s_slug"),
        ]

    # 2. ClassVar prefix
    __prefix__: ClassVar[str] = "xxx"

    # 3. Identifiers — primary key, slugs, external refs
    id = models.CharField(
        max_length=64, primary_key=True, default=generate_xxx_id, editable=False
    )
    slug = models.SlugField(max_length=255)

    # 4. Time fields — created, updated, any dates/datetimes
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    # 5. Workflow / status / state (if applicable)
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default="draft")

    # 6. Everything else — domain fields
    name = models.CharField(max_length=255)
    description = models.TextField(blank=True)

    # 7. Relations — ForeignKey, OneToOne, ManyToMany (always last among fields)
    category = models.ForeignKey("categories.Category", on_delete=models.CASCADE)

    # 8. __str__ — only if useful, and the only method allowed
    def __str__(self) -> str:
        return self.name

Rules

Meta First

class Meta is always the first thing inside the model body — before __prefix__, before the primary key, before any field. This is non-negotiable. It puts the most important structural information (naming, indexes, ordering, constraints) at the top where it's immediately visible.

The ordering inside Meta itself:

  1. verbose_name and verbose_name_plural
  2. indexes
  3. constraints (unique constraints, check constraints)
  4. Anything else (ordering, abstract, etc.)
Always Declare verbose_name and verbose_name_plural

Every model's Meta must include both:

python
class Meta:
    verbose_name = "order item"
    verbose_name_plural = "order items"
  • Use lowercase, human-readable English
  • Never rely on Django's automatic pluralization — it gets edge cases wrong ("categorys", "order items" → "order itemss")
  • The verbose_name should read naturally in admin headers and log messages
Field Ordering

Fields are grouped by role, in this order:

  1. Identifiers — primary key, slugs, external reference codes, SKUs
  2. Time fields — created_at, updated_at, published_at, any date or datetime
  3. Workflow / status / state — status, stage, is_active, is_published (skip if the model has no lifecycle)
  4. Domain fields — everything else: name, description, price, quantity, etc.
  5. Relations — ForeignKey, OneToOneField, ManyToManyField — always last among fields

This ordering makes scanning a model top-to-bottom predictable: "what is it, when was it, where is it in its lifecycle, what does it contain, what does it relate to."

Uniqueness and Constraints in Meta

All uniqueness and constraints are declared in Meta.constraints — never use unique=True on individual fields. This keeps all structural rules in one place, right at the top of the model.

python
class Meta:
    verbose_name = "product"
    verbose_name_plural = "products"
    indexes = [
        models.Index(fields=["-created_at"], name="idx_%(class)s_recent"),
    ]
    constraints = [
        models.UniqueConstraint(fields=["sku"], name="uq_%(class)s_sku"),
        models.UniqueConstraint(fields=["store", "slug"], name="uq_%(class)s_store_slug"),
        models.CheckConstraint(check=models.Q(price__gte=0), name="ck_%(class)s_price_pos"),
    ]

Constraint naming convention:

  • Unique: uq_%(class)s_<short_description>
  • Check: ck_%(class)s_<short_description>

UniqueConstraint is strictly more powerful than unique=True — it supports multi-column uniqueness, conditional uniqueness (condition=), and naming. Use it exclusively.

Field verbose_name and help_text

Any field whose name is more than one word (joined by underscores) should have an explicit verbose_name so it reads cleanly in the admin:

python
price_at_purchase = models.DecimalField(
    verbose_name="price at purchase",
    max_digits=10,
    decimal_places=2,
)

Any field whose purpose is not immediately obvious from its name needs help_text. This shows up in the admin form below the field and serves as inline documentation:

python
idempotency_key = models.CharField(
    max_length=255,
    help_text="Client-generated key to prevent duplicate order submissions.",
)
retention_days = models.IntegerField(
    verbose_name="retention days",
    default=90,
    help_text="Number of days to retain this record before archival.",
)

Rules:

  • Single-word fields (name, price, status) don't need a verbose_name — Django infers it fine
  • Multi-word fields (price_at_purchase, is_published, created_by) always get an explicit verbose_name
  • Obscure or domain-specific fields always get help_text — if a new developer would need to ask "what is this?", add it
  • Keep help_text to one sentence, written for someone reading the admin form
Specify Indexes in Meta

All indexes are declared in Meta.indexes — never use db_index=True on individual fields. Centralizing indexes makes them reviewable at a glance and enables composite indexes that db_index=True cannot express.

python
class Meta:
    verbose_name = "order"
    verbose_name_plural = "orders"
    indexes = [
        models.Index(fields=["customer", "created_at"], name="idx_%(class)s_cust_created"),
        models.Index(fields=["status", "-created_at"], name="idx_%(class)s_status_recent"),
    ]

Index naming convention: idx_%(class)s_<short_description> — Django interpolates %(class)s to the lowercased model name, keeping names unique across models.

Optimize Indexes for How the Model Is Used

Don't index speculatively. Read the repository that queries this model and index for the queries that actually exist:

  • Filter + order → composite index with filter columns first, order column last: fields=["status", "-created_at"]
  • Foreign key lookups → Django auto-creates indexes on ForeignKey fields, but if you always filter the FK with another column, replace it with a composite: fields=["order", "product"]
  • Prefix for descending sort → use - prefix: fields=["-created_at"] for queries that ORDER BY created_at DESC
  • Covering queries → if a query only reads a small set of columns, consider include (Postgres): models.Index(fields=["status"], include=["total"], name="idx_%(class)s_status_cov")
  • Partial indexes → if a query always filters on a condition, use condition: models.Index(fields=["created_at"], condition=models.Q(status="pending"), name="idx_%(class)s_pending")
  • Don't duplicate — Django auto-creates an index for every ForeignKey and UniqueConstraint. Don't add a redundant single-column index for those.
  • Don't over-index — every index slows writes. Three or four well-chosen indexes beat eight speculative ones.
No Business Logic

Models contain ZERO business logic:

  • No custom managers
  • No save() overrides
  • No signals
  • No properties that compute
  • __str__ is the only method allowed — and only if it adds value (skip it if the default ModelName object (pk) is fine)

Admin Registration

Every model gets registered in src/<app>/admin.py with a clean, fast-loading configuration. The admin should be aesthetic — well-organized, readable, and snappy even on large tables.

python
from django.contrib import admin

from .models.order import Order, OrderItem


class OrderItemInline(admin.TabularInline):
    model = OrderItem
    fields = ("id", "product", "quantity", "price_at_purchase")
    readonly_fields = ("id",)
    extra = 0
    show_change_link = True


@admin.register(Order)
class OrderAdmin(admin.ModelAdmin):
    list_display = ("id", "date", "total")
    list_per_page = 25
    search_fields = ("id",)
    readonly_fields = ("id",)
    ordering = ("-date",)
    fieldsets = (
        (None, {"fields": ("id", "date")}),
        ("Details", {"fields": ("total",)}),
    )
    inlines = [OrderItemInline]
Show full SKILL.md (786 more words)Show less
Admin Rules
  • list_display — id first, then the most useful columns. Keep it to 4-6 fields max for readability.

  • list_per_page = 25 — default 100 is too slow on large tables. 25 keeps the admin snappy.

  • search_fields — always include id. Add name/title fields if they exist. Never search on unindexed columns.

  • readonly_fields — always include id (ULID PKs should never be edited). Add computed or auto-set fields.

  • ordering — explicit ordering so the admin doesn't rely on the default PK sort. Use -created_at or the most natural time field.

  • fieldsets — structure the change view semantically in three bands. Always follow this exact pattern:

    1. Untitled (None) fieldset — primary key and identity fields only (id, plus email / slug / natural key if the model has one). Renders with no collapsible header so identifiers are always visible at the top.
    2. Named semantic sections — group remaining fields by meaning, not DB column order. Reusable section names: "Personal Info", "Details", "Role & Permissions", "Security", "Relations". Use "Details" as the catchall when no more specific name fits.
    3. "Important Dates" (always last) — every datetime field goes here: created_at, updated_at, deleted_at, last_login, date_joined, etc. Title is exactly "Important Dates" (title case).
    python
    fieldsets = (
        (None, {"fields": ("id", "slug")}),
        ("Details", {"fields": ("name", "description", "status")}),
        ("Relations", {"fields": ("category",)}),
        ("Important Dates", {"fields": ("created_at", "updated_at")}),
    )

    Rationale: identity at top (always visible), domain in the middle (named so it's scannable), dates at the bottom (rarely the thing you're editing, and separating them keeps the top fieldset focused on identity).

  • add_fieldsets — for models that support admin creation (User primarily), provide a minimal add_fieldsets with just the required fields for a new record:

    python
    add_fieldsets = (
        (None, {
            "classes": ("wide",),
            "fields": ("email", "password1", "password2"),
        }),
    )

    Keeps the "Add" form focused — the full fieldsets is for editing, not creation.

  • list_select_related — specify FK fields shown in list_display to avoid N+1 queries: list_select_related = ("customer",)

  • raw_id_fields — use for any FK to a large table. The default dropdown loads every row: raw_id_fields = ("product",)

  • extra = 0 on inlines — never show empty inline forms by default.

  • show_change_link = True on inlines — lets you click through to the inline's own admin page.

  • TabularInline for child models on the parent's admin.

  • No list_filter on unindexed columns — filtering on unindexed columns causes full table scans.

  • autocomplete_fields — prefer over raw_id_fields when the related model has search_fields configured for a better UX: autocomplete_fields = ("customer",)

  • date_hierarchy — use on the primary date field if the model is time-series-like (orders, events, logs). Only use on indexed date fields.

Admin Actions

Custom admin actions (the dropdown users select from on the changelist) MUST be thin adapters — never the home of business logic. The action receives a queryset, iterates it, delegates each row to a registered service via get(Service), and reports the result via self.message_user(request, ...).

python
from django.contrib import admin

from products.services.product import ProductService
from project.services import get


@admin.register(Order)
class OrderAdmin(admin.ModelAdmin):
    actions = ["fulfill_selected_action"]

    @admin.action(description="Fulfill selected orders")
    def fulfill_selected_action(self, request, queryset):
        count = 0
        for order in queryset:
            get(ProductService).fulfill_order(order.id)
            count += 1
        self.message_user(request, f"Fulfilled {count} orders.")

Rules:

  1. Named <verb>_<noun>_action and listed in actions = [...]. The _action suffix distinguishes them from regular ModelAdmin methods at a glance.
  2. @admin.action(description="...") is mandatory — the description is what users see in the dropdown. No emojis, no ALL-CAPS shouting.
  3. Delegate to a service via get(Service).method(id). The action body MUST NOT contain ORM queries beyond iterating the incoming queryset, MUST NOT compute business logic, MUST NOT call external APIs directly.
  4. Pass IDs, not model instances, to the service. Matches the rest of the architecture — services deal in DTOs and str IDs.
  5. Call self.message_user() with a result summary — count, or a short outcome description. This is what users see after running the action.
  6. Do NOT build Celery chains/groups in the action. If the operation needs async orchestration, build the chain inside the service method; the action stays a thin adapter.
  7. Error handling — plain exceptions bubble up and Django renders them appropriately. Do not try/except in the action body; the service is where error semantics live.

Full Example

python
from typing import ClassVar

from django.db import models

from products.models.product import Product
from project.ids import generate_itm_id, generate_ord_id


class Order(models.Model):
    class Meta:
        verbose_name = "order"
        verbose_name_plural = "orders"
        indexes = [
            models.Index(fields=["-date"], name="idx_%(class)s_recent"),
            models.Index(fields=["status", "-date"], name="idx_%(class)s_status_recent"),
        ]
        constraints = [
            models.UniqueConstraint(
                fields=["idempotency_key"],
                name="uq_%(class)s_idempotency",
            ),
        ]

    __prefix__: ClassVar[str] = "ord"

    # Identifiers
    id = models.CharField(
        max_length=64, primary_key=True, default=generate_ord_id, editable=False
    )
    idempotency_key = models.CharField(
        verbose_name="idempotency key",
        max_length=255,
        help_text="Client-generated key to prevent duplicate order submissions.",
    )

    # Time
    date = models.DateTimeField(auto_now_add=True)

    # Status
    status = models.CharField(max_length=20, default="pending")

    # Domain
    total = models.DecimalField(max_digits=12, decimal_places=2)

    def __str__(self) -> str:
        return f"Order {self.id} on {self.date}"


class OrderItem(models.Model):
    class Meta:
        verbose_name = "order item"
        verbose_name_plural = "order items"
        indexes = [
            models.Index(fields=["order", "product"], name="idx_%(class)s_ord_prd"),
        ]

    __prefix__: ClassVar[str] = "itm"

    # Identifiers
    id = models.CharField(
        max_length=64, primary_key=True, default=generate_itm_id, editable=False
    )

    # Domain
    quantity = models.PositiveIntegerField()
    price_at_purchase = models.DecimalField(
        verbose_name="price at purchase",
        max_digits=10,
        decimal_places=2,
        help_text="Snapshot of the product price at the time the order was placed.",
    )

    # Relations
    order = models.ForeignKey(Order, related_name="items", on_delete=models.CASCADE)
    product = models.ForeignKey(Product, on_delete=models.CASCADE)

    def __str__(self) -> str:
        return f"{self.quantity} x {self.product.name} (Order {self.order_id})"  # type: ignore[attr-defined]

Admin for the example above:

python
from django.contrib import admin

from .models.order import Order, OrderItem


class OrderItemInline(admin.TabularInline):
    model = OrderItem
    fields = ("id", "product", "quantity", "price_at_purchase")
    readonly_fields = ("id",)
    extra = 0
    show_change_link = True


@admin.register(Order)
class OrderAdmin(admin.ModelAdmin):
    list_display = ("id", "status", "date", "total")
    list_per_page = 25
    search_fields = ("id", "idempotency_key")
    readonly_fields = ("id", "date")
    ordering = ("-date",)
    date_hierarchy = "date"
    fieldsets = (
        (None, {"fields": ("id", "date")}),
        ("Details", {"fields": ("status", "total", "idempotency_key")}),
    )
    inlines = [OrderItemInline]

Verify

After creating or modifying models:

bash
uv run python src/manage.py makemigrations && uv run python src/manage.py migrate
uv run ruff check src
uv run ruff format --check src
uv run pyrefly check src
uv run pytest

All must pass. Fix any issue rather than silencing it.

Checklist

  • class Meta is the first thing inside the model body
  • verbose_name and verbose_name_plural are set — never relying on Django's auto-pluralization
  • Field order: identifiers → time → status/state → domain → relations
  • All indexes in Meta.indexes — no db_index=True on fields
  • All uniqueness in Meta.constraints via UniqueConstraint — no unique=True on fields
  • Check constraints in Meta.constraints where applicable
  • Indexes match actual query patterns from the repository layer
  • No over-indexing — only index what is queried
  • Multi-word fields have explicit verbose_name
  • Obscure or domain-specific fields have help_text
  • No business logic — no custom managers, save(), signals, or computed properties
  • __str__ only if useful, and the only method allowed
  • Model registered in admin with list_display, list_per_page = 25, search_fields, readonly_fields, ordering, fieldsets
  • fieldsets places id and timestamps in the first (untitled) fieldset at the top of the change view
  • FKs to large tables use raw_id_fields or autocomplete_fields
  • Inlines use extra = 0 and show_change_link = True
  • Migrations generated and applied
  • ruff, pyrefly, pytest all pass

© dvf, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in skills/dj-models of dvf/opinionated-django.

Open the folder on GitHubat commit f17fc2d

Compare with similar skills

Dj Models next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Dj Models compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Dj Models this skilldvf/opinionated-django109—~4.9kAutomated safety check: NotesMIT
Saleor Django Schema Migrationsaleor/saleor23k—~1kAutomated safety check: PassBSD-3-Clause
Django Access Reviewgetsentry/skills1k3 repos~2.6kAutomated safety check: NotesApache-2.0
Silk Profilerbaserow/baserow6.1k—~2.9kAutomated safety check: PassCustom licence
Arch Wikiahmedemad3/arch-wiki249—~5.1kAutomated safety check: PassNone
Run Testsnetboxlabs/netbox-branching155—~1.2kAutomated safety check: PassCustom licence

Similar skills

  • Generates and splits Django schema migrations for Saleor with manage.py makemigrations, enforcing one new model or one field change per migration file.

    23k GitHub stars~1k tokensUpdated yesterday
    Backend & APIsAuto-check passed
  • Django Access Review

    getsentry/skills

    Official

    Django access control and IDOR security review. An agent skill from getsentry/skills.

    1k GitHub starsUsed in 3 repos~2.6k tokens
    Backend & APIsAuto-check: notes
  • Silk Profiler

    baserow/baserow

    Investigate backend performance using Django Silk profiling data.

    6.1k GitHub stars~2.9k tokensUpdated today
    Backend & APIsAuto-check passed
  • Arch Wiki

    ahmedemad3/arch-wiki

    Scans any project codebase for new/changed modules, endpoints, middleware, infrastructure, Docker topologies, SQL queries, or permissions and updates docs/architecture/architecture.json.

    249 GitHub stars~5.1k tokensUpdated 18 days ago
    Backend & APIsAuto-check passed
  • Run Tests

    netboxlabs/netbox-branching

    Run the netboxbranching plugin's Django test suite against a local NetBox checkout.

    155 GitHub stars~1.2k tokensUpdated today
    Backend & APIsAuto-check passed
  • Add or change a CLIST Django management command, including arguments, resource selection, EventLog monitoring, or cron and Healthchecks wiring.

    439 GitHub stars~848 tokensUpdated 2 days ago
    Backend & APIsAuto-check passed

More from dvf/opinionated-django

All 9 skills in this repo
  • Dj Architecture

    dvf/opinionated-django

    Implement a Django feature following the opinionated architecture — prefixed ULID IDs, repository pattern, Pydantic DTOs, svcs service locator, project-scoped django-ninja API, Celery reliable…

    109 GitHub stars~4k tokensUpdated 1 mo ago
    Auto-check: notes
  • Dj Prefixed Ulids

    dvf/opinionated-django

    Use Stripe-style prefixed ULID primary keys (e.g. An agent skill from dvf/opinionated-django.

    109 GitHub stars~1.4k tokensUpdated 1 mo ago
    Auto-check: notes
  • Dj Pytest

    dvf/opinionated-django

    Set up and write pytest tests for an op-django project — pytest-django configuration, two-sided Celery testing (patched dispatch sites + plain-function task bodies, never eager mode), freezegun for…

    109 GitHub stars~4.3k tokensUpdated 1 mo ago
    Auto-check: notes
  • Dj Scaffold

    dvf/opinionated-django

    Set up a Django project into the op-django layout so the architecture, signals, and settings skills have a foundation to build on.

    109 GitHub stars~3.3k tokensUpdated 1 mo ago
    Auto-check: notes
  • Dj Services

    dvf/opinionated-django

    Structure Django business logic as plain services that receive their dependencies via constructor injection, and wire them through an svcs registry so they can be resolved anywhere — views, Celery…

    109 GitHub stars~3k tokensUpdated 1 mo ago
    Auto-check: notes
  • Dj Signals

    dvf/opinionated-django

    Add reliable signals (async side-effects via Celery) to a Django feature.

    109 GitHub stars~1k tokensUpdated 1 mo ago
    Auto-check: notes

Works with

Categories

Questions about Dj Models

What does Dj Models do?

Structure Django models with proper Meta classes, verbose names, and optimized indexes. Dj Models is an agent skill from dvf/opinionated-django. Structure Django models with proper Meta classes, verbose names, and optimized indexes.

When should I use Dj Models?

Dj Models fits situations like: reviewing Django models to ensure consistent ordering; correct verbosename/verbosenameplural; database indexes aligned to actual query patterns.

How do I install Dj Models in Claude Code?

Run `npx skills add dvf/opinionated-django --skill dj-models -a claude-code`. Or copy the skill folder (skills/dj-models in dvf/opinionated-django) into .claude/skills/dj-models in your project. Claude Code loads it when a task matches its description.

How do I install Dj Models in Codex?

Run `npx skills add dvf/opinionated-django --skill dj-models -a codex`. Or copy the skill folder (skills/dj-models in dvf/opinionated-django) into .agents/skills/dj-models in your project. Codex loads it when a task matches its description.

Can I use Dj Models in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add dvf/opinionated-django --skill dj-models -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/dj-models, .gemini/skills/dj-models, .github/skills/dj-models and .opencode/skills/dj-models in your project.

What does Dj Models need to run?

Going by SKILL.md and its folder, Dj Models needs the command-line tools its instructions call (uv). Our summary lists: Python 3. Its frontmatter pre-approves these tools: Read, Write, Edit, Bash, Grep, Glob.

Does Dj Models access the network?

SKILL.md contains no URLs. Its commands use uv, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Dj Models safe to install?

Our automated static check of SKILL.md found notes only (pre-approves every shell command (allowed-tools: bash)), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.

What licence does Dj Models use?

Dj Models is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Dj Models use?

About 4.9k tokens (SKILL.md is roughly 19k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Dj Models?

Skills that share tags, products or a category with Dj Models: Saleor Django Schema Migration (saleor/saleor, 23k stars), Django Access Review (getsentry/skills, 1k stars), Silk Profiler (baserow/baserow, 6.1k stars) and Arch Wiki (ahmedemad3/arch-wiki, 249 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Dj Models?

dvf (a GitHub user) maintains it in dvf/opinionated-django, which has 109 GitHub stars. The repository holds 9 skills in this directory. The repository was last updated on August 14, 2026.

Source: dvf/opinionated-django on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.