Files
DjangoAdmin_Django_EleVue/CLAUDE.md
T
2026-09-11 11:39:07 +08:00

7.5 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

What this is

DjangoAdmin (Django + EleVue) is a low-code admin framework: a full CRUD module — Django app, Vue view, API module, menu & permission records — is generated from a database table definition, not hand-written. The code generator is the heart of the project; the application/example/ module and config.json at the repo root are samples of its output.

  • Backend: Django 6.0.3 + DRF (installed, but views are plain Django View classes), MySQL, Redis, JWT auth. All in Python under application/.
  • Frontend: Vue 3 + TypeScript + Element Plus + Pinia + Vite, in ui/. Derived from the vben-admin architecture.
  • Both sides are heavily documented in Chinese docstrings/comments; code identifiers and API field names are English.

Commands

Backend (repo root)

Dependencies: requirements.txt is UTF-16LE encoded — pip install -r requirements.txt may fail on some platforms; re-save it as UTF-8 first if so. MySQL and Redis must be running; all connection settings live in .env (loaded by config/env.py, imported everywhere as from config.env import ...).

python manage.py runserver                        # http://127.0.0.1:8000
python manage.py makemigrations <app> && python manage.py migrate
python manage.py test
python manage.py add_full_comments                # custom command: backfill DB field comments

application/settings.py hardcodes DEBUG = True; switch behavior via .env values (e.g. DJANGO_DEMO=True blocks all write endpoints with a demo message).

Code generator CLI (repo root)

python generator.py django_<table>                 # parse DB table -> config.json -> generate module + Vue + menus
python generator.py django_<table> --dry-run       # only print config (add --output config.json to save it)
python generator.py --config config.json           # generate code from an existing config file

Equivalent web UI exists at /generator (the application/generator app). Backend code runs python generator.py ... from the repo root with the venv active.

Frontend (ui/)

cd ui
pnpm install        # (package.json also aliases this as "bootstrap")
pnpm dev            # http://localhost:8001; proxies /api -> http://127.0.0.1:8000/ (see ui/.env.development)
pnpm build          # prod build
pnpm type:check     # vue-tsc --noEmit
pnpm lint:eslint && pnpm lint:prettier && pnpm lint:stylelint

Architecture

The code generator (read these three to understand the whole project)

  1. generator.py — TableSchemaParser introspects a MySQL table (field type/comment/length/index) and heuristically classifies fields (image, rich-text, status, sort, code, filterable, choices) into a JSON "config" like the checked-in config.json.
  2. generator_config.py — CodeGenerator consumes that config, renders Jinja2 templates from public/templates/ (e.g. *.py.tpl, ui/*.vue.tpl), and writes:
    • backend module files under application/<module>/ (models/forms/services/views/urls/admin/apps + a migration),
    • Vue files under ui/src/views/... and an API module under ui/src/api/tool/<module>.ts,
    • then runs makemigrations/migrate, inserts menu + permission nodes into the DB (application.menu.models.Menu), and appends the route to application/urls.py and the app to INSTALLED_APPS in application/settings.py.
  3. application/generator/ — web endpoint wrapper around the same logic (services.generate_tables).

Adding a table → config → generated module is the normal way new features are built; don't hand-write a full module unless you need custom logic.

Backend module pattern

Every app under application/<module>/ follows the same generated layout:

  • models.py — inherits abstract BaseModel (application/models.py): id, create_user, create_time, update_user, update_time, is_delete. All queries filter is_delete=False (soft delete).
  • forms.py — Django ModelForm with per-field validation and Chinese error_messages.
  • services.py — all business logic lives here, in functions like get_<m>_page, add_<m>, update_<m>, delete_<m> (batch delete via comma-joined IDs), update_<m>_status. Uses parse_request_body + regular.get_err from utils/. Pagination via Django Paginator; response shape {records, total, size, current, pages}.
  • views.py — one class per endpoint, each @method_decorator(check_login, name="<method>"), subclassing PermissionRequired with permission_required = ("sys:<module>:<action>",), and write/read handlers decorated with @operation_log(title=..., log_type=LogType.<X>) from application/operation_log/decorators.py.
  • urls.py — declared per-module, wired into application/urls.py (each path is a module prefix like level/, dict/item/, role/menu/).

Convention: DB/field names are snake_case; JSON payloads use camelCase (create_user ↔ createUser). Views/services build dicts manually per record.

Auth & permissions

  • check_login (middleware/login_middleware.py) validates the Authorization: Bearer <token> JWT (parsed by utils/jwts.py); ignoreURL = ['/login', '/captcha'].
  • PermissionRequired (middleware/permission_middleware.py) — user id 1 is superadmin (bypass), otherwise checks the sys:<module>:<action> node against application/menu/services.get_user_permissions(user_id).
  • Frontend hides/disable buttons with the v-perm directive using the same sys:... codes.

Response convention

utils/R.py — every endpoint returns R.ok(...) / R.failed(...), envelope {code: 0/1, data, msg, ok}. Read it before writing a view.

Frontend (ui/)

  • Routes and menus are dynamic, driven by the backend. On login the router guard (src/router/router-guards.ts → generator-routers.ts) calls GET /index/getMenus, and the returned menu tree becomes Vue Router records + <el-menu> items. Each menu row's component field must match a .vue under src/views/** (resolved via import.meta.glob). So new pages appear by inserting a menu row in the DB, not by editing a frontend route file.
  • API modules live under src/api/<domain>/<name>.ts, importing http from @/utils/http/axios (base /api, JWT header injection, unwraps {code, data, msg}). See src/api/tool/example.ts for the canonical CRUD shape.
  • A generated CRUD view is a folder src/views/<domain>/<entity>/ with index.vue (search BasicForm via useForm + querySchemas.ts, list BasicTable + columns.ts, TableAction row buttons), plus lazy-loaded edit.vue / detail.vue dialogs. Shared components: BasicTable, BasicForm, PageWrapper from src/components/. Store: Pinia in src/store/modules/ (notably asyncRoute.ts, user.ts).
  • Dev networking: Vite on 8001 proxies /api to Django 127.0.0.1:8000 (.env.development); change backend target there.

Conventions to follow

  • Every source file begins with a long Chinese copyright banner from 小蚂蚁云团队 — keep it on new files (including generator output).
  • Docs/comments are in Chinese; identifiers, APIs, and commit-adjacent names in English.
  • New modules should be produced through the generator where possible; if writing one by hand, mirror application/example/ exactly (models/forms/services/views/urls) and remember to register the app in settings.py INSTALLED_APPS and add its routes to application/urls.py.
  • Permissions are sys:<module>:<action> for actions page/list/detail/add/update/delete/status.