Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Verification loop for Django projects: migrations, linting, tests with coverage, security scans, and deployment readiness checks before release or PR.
.claude/skills/affaan-m-django-verification/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-07 | ✗→✓ | ▲ Improved | 131% | 0% |
| case-19 | ✗→✓ | ▲ Improved | 113% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 192% | 0% |
| case-06 | ✓→✓ | = Same ✓ | 157% | 0% |
| case-09 | ✓→✓ | = Same ✓ | 97% | 0% |
在发起 PR 之前、进行重大更改之后以及部署之前运行,以确保 Django 应用程序的质量和安全性。
bash# Verify Python version python --version # Should match project requirements # Check virtual environment which python pip list --outdated # Verify environment variables python -c "import os; import environ; print('DJANGO_SECRET_KEY set' if os.environ.get('DJANGO_SECRET_KEY') else 'MISSING: DJANGO_SECRET_KEY')"
如果环境配置错误,请停止并修复。
bash# Type checking mypy . --config-file pyproject.toml # Linting with ruff ruff check . --fix # Formatting with black black . --check black . # Auto-fix # Import sorting isort . --check-only isort . # Auto-fix # Django-specific checks python manage.py check --deploy
常见问题:
bash# Check for unapplied migrations python manage.py showmigrations # Create missing migrations python manage.py makemigrations --check # Dry-run migration application python manage.py migrate --plan # Apply migrations (test environment) python manage.py migrate # Check for migration conflicts python manage.py makemigrations --merge # Only if conflicts exist
报告:
bash# Run all tests with pytest pytest --cov=apps --cov-report=html --cov-report=term-missing --reuse-db # Run specific app tests pytest apps/users/tests/ # Run with markers pytest -m "not slow" # Skip slow tests pytest -m integration # Only integration tests # Coverage report open htmlcov/index.html
报告:
覆盖率目标:
| 组件 | 目标 | |-----------|--------| | 模型 | 90%+ | | 序列化器 | 85%+ | | 视图 | 80%+ | | 服务 | 90%+ | | 总体 | 80%+ |
bash# Dependency vulnerabilities pip-audit safety check --full-report # Django security checks python manage.py check --deploy # Bandit security linter bandit -r . -f json -o bandit-report.json # Secret scanning (if gitleaks is installed) gitleaks detect --source . --verbose # Environment variable check python -c "from django.core.exceptions import ImproperlyConfigured; from django.conf import settings; settings.DEBUG"
报告:
bash# Check for model issues python manage.py check # Collect static files python manage.py collectstatic --noinput --clear # Create superuser (if needed for tests) echo "from apps.users.models import User; User.objects.create_superuser('admin@example.com', 'admin')" | python manage.py shell # Database integrity python manage.py check --database default # Cache verification (if using Redis) python -c "from django.core.cache import cache; cache.set('test', 'value', 10); print(cache.get('test'))"
bash# Django Debug Toolbar output (check for N+1 queries) # Run in dev mode with DEBUG=True and access a page # Look for duplicate queries in SQL panel # Query count analysis django-admin debugsqlshell # If django-debug-sqlshell installed # Check for missing indexes python manage.py shell << EOF from django.db import connection with connection.cursor() as cursor: cursor.execute("SELECT table_name, index_name FROM information_schema.statistics WHERE table_schema = 'public'") print(cursor.fetchall()) EOF
报告:
bash# Check for npm dependencies (if using npm) npm audit npm audit fix # Build static files (if using webpack/vite) npm run build # Verify static files ls -la staticfiles/ python manage.py findstatic css/style.css
python# Run in Python shell to verify settings python manage.py shell << EOF from django.conf import settings import os # Critical checks checks = { 'DEBUG is False': not settings.DEBUG, 'SECRET_KEY set': bool(settings.SECRET_KEY and len(settings.SECRET_KEY) > 30), 'ALLOWED_HOSTS set': len(settings.ALLOWED_HOSTS) > 0, 'HTTPS enabled': getattr(settings, 'SECURE_SSL_REDIRECT', False), 'HSTS enabled': getattr(settings, 'SECURE_HSTS_SECONDS', 0) > 0, 'Database configured': settings.DATABASES['default']['ENGINE'] != 'django.db.backends.sqlite3', } for check, result in checks.items(): status = '✓' if result else '✗' print(f"{status} {check}") EOF
bash# Test logging output python manage.py shell << EOF import logging logger = logging.getLogger('django') logger.warning('Test warning message') logger.error('Test error message') EOF # Check log files (if configured) tail -f /var/log/django/django.log
bash# Generate schema python manage.py generateschema --format openapi-json > schema.json # Validate schema # Check if schema.json is valid JSON python -c "import json; json.load(open('schema.json'))" # Access Swagger UI (if using drf-yasg) # Visit http://localhost:8000/swagger/ in browser
bash# Show diff statistics git diff --stat # Show actual changes git diff # Show changed files git diff --name-only # Check for common issues git diff | grep -i "todo\|fixme\|hack\|xxx" git diff | grep "print(" # Debug statements git diff | grep "DEBUG = True" # Debug mode git diff | grep "import pdb" # Debugger
检查清单:
DJANGO 验证报告
==========================
阶段 1:环境检查
✓ Python 3.11.5
✓ 虚拟环境已激活
✓ 所有环境变量已设置
阶段 2:代码质量
✓ mypy: 无类型错误
✗ ruff: 发现 3 个问题(已自动修复)
✓ black: 无格式问题
✓ isort: 导入已正确排序
✓ manage.py check: 无问题
阶段 3:数据库迁移
✓ 无未应用的迁移
✓ 无迁移冲突
✓ 所有模型均有对应的迁移文件
阶段 4:测试与覆盖率
测试:247 通过,0 失败,5 跳过
覆盖率:
总计:87%
users: 92%
products: 89%
orders: 85%
payments: 91%
阶段 5:安全扫描
✗ pip-audit: 发现 2 个漏洞(需要修复)
✓ safety check: 无问题
✓ bandit: 无安全问题
✓ 未检测到密钥泄露
✓ DEBUG = False
阶段 6:Django 命令
✓ collectstatic 完成
✓ 数据库完整性正常
✓ 缓存后端可访问
阶段 7:性能
✓ 未检测到 N+1 查询
✓ 数据库索引已配置
✓ 查询数量可接受
阶段 8:静态资源
✓ npm audit: 无漏洞
✓ 资源构建成功
✓ 静态文件已收集
阶段 9:配置
✓ DEBUG = False
✓ SECRET_KEY 已配置
✓ ALLOWED_HOSTS 已设置
✓ HTTPS 已启用
✓ HSTS 已启用
✓ 数据库已配置
阶段 10:日志
✓ 日志配置完成
✓ 日志文件可写入
阶段 11:API 文档
✓ 架构已生成
✓ Swagger UI 可访问
阶段 12:差异审查
文件变更:12
行数变化:+450, -120
✓ 无调试语句
✓ 无硬编码密钥
✓ 包含迁移文件
建议:WARNING: 部署前修复 pip-audit 发现的漏洞
后续步骤:
1. 更新存在漏洞的依赖项
2. 重新运行安全扫描
3. 部署到预发布环境进行最终测试yaml# .github/workflows/django-verification.yml name: Django Verification on: [push, pull_request] jobs: verify: runs-on: ubuntu-latest services: postgres: image: postgres:14 env: POSTGRES_PASSWORD: postgres options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 steps: - uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.11' - name: Cache pip uses: actions/cache@v3 with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} - name: Install dependencies run: | pip install -r requirements.txt pip install ruff black mypy pytest pytest-django pytest-cov bandit safety pip-audit - name: Code quality checks run: | ruff check . black . --check isort . --check-only mypy . - name: Security scan run: | bandit -r . -f json -o bandit-report.json safety check --full-report pip-audit - name: Run tests env: DATABASE_URL: postgres://postgres:postgres@localhost:5432/test DJANGO_SECRET_KEY: test-secret-key run: | pytest --cov=apps --cov-report=xml --cov-report=term-missing - name: Upload coverage uses: codecov/codecov-action@v3
| 检查项 | 命令 | |-------|---------| | 环境 | python --version | | 类型检查 | mypy . | | 代码检查 | ruff check . | | 格式化 | black . --check | | 迁移 | python manage.py makemigrations --check | | 测试 | pytest --cov=apps | | 安全 | pip-audit && bandit -r . | | Django 检查 | python manage.py check --deploy | | 收集静态文件 | python manage.py collectstatic --noinput | | 差异统计 | git diff --stat |
请记住:自动化验证可以发现常见问题,但不能替代在预发布环境中的手动代码审查和测试。
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-08 | fail→fail | 14,094 | 12,210 | -13% | 1 | 1 | 0% | 2,426 | 5,350 | +121% | 0 | 0 | — |
case-01 | fail→fail | 20,701 | 13,509 | -35% | 1 | 1 | 0% | 3,502 | 5,763 | +65% | 0 | 0 | — |
case-02 | fail→fail | 18,241 | 18,814 | +3% | 1 | 1 | 0% | 3,808 | 7,009 | +84% | 0 | 0 | — |
case-03 | fail→fail | 18,364 | 17,756 | -3% | 1 | 1 | 0% | 2,372 | 5,428 | +129% | 0 | 0 | — |
case-04 | pass→pass | 10,974 | 13,191 | +20% | 1 | 1 | 0% | 1,965 | 5,747 | +192% | 0 | 0 | — |
case-05 | fail→fail | 13,467 | 16,592 | +23% | 1 | 1 | 0% | 2,477 | 6,466 | +161% | 0 | 0 | — |
case-06 | pass→pass | 12,839 | 14,550 | +13% | 1 | 1 | 0% | 2,217 | 5,688 | +157% | 0 | 0 | — |
case-07 | fail→pass | 14,959 | 14,405 | -4% | 1 | 1 | 0% | 2,325 | 5,364 | +131% | 0 | 0 | — |
case-09 | pass→pass | 11,765 | 4,795 | -59% | 1 | 1 | 0% | 1,987 | 3,909 | +97% | 0 | 0 | — |
case-10 | pass→pass | 7,863 | 3,986 | -49% | 1 | 1 | 0% | 1,368 | 3,804 | +178% | 0 | 0 | — |
case-11 | pass→pass | 2,810 | 2,519 | -10% | 1 | 1 | 0% | 422 | 3,517 | +733% | 0 | 0 | — |
case-12 | pass→pass | 12,852 | 9,825 | -24% | 1 | 1 | 0% | 1,977 | 4,744 | +140% | 0 | 0 | — |
case-13 | pass→pass | 14,104 | 10,944 | -22% | 1 | 1 | 0% | 2,716 | 5,174 | +91% | 0 | 0 | — |
case-14 | pass→pass | 10,645 | 4,823 | -55% | 1 | 1 | 0% | 1,802 | 3,944 | +119% | 0 | 0 | — |
case-15 | pass→pass | 14,801 | 12,919 | -13% | 1 | 1 | 0% | 2,550 | 5,234 | +105% | 0 | 0 | — |
case-16 | pass→pass | 4,358 | 3,037 | -30% | 1 | 1 | 0% | 712 | 3,642 | +412% | 0 | 0 | — |
case-17 | pass→pass | 4,652 | 3,664 | -21% | 1 | 1 | 0% | 840 | 3,763 | +348% | 0 | 0 | — |
case-18 | pass→pass | 3,100 | 3,934 | +27% | 1 | 1 | 0% | 506 | 3,851 | +661% | 0 | 0 | — |
case-19 | fail→pass | 13,380 | 13,162 | -2% | 1 | 1 | 0% | 2,524 | 5,372 | +113% | 0 | 0 | — |
case-20 | pass→pass | 11,762 | 6,235 | -47% | 1 | 1 | 0% | 1,855 | 4,046 | +118% | 0 | 0 | — |
case-21 | fail→fail | 12,481 | 9,977 | -20% | 1 | 1 | 0% | 2,402 | 5,150 | +114% | 0 | 0 | — |
case-22 | pass→pass | 2,984 | 3,584 | +20% | 1 | 1 | 0% | 493 | 3,694 | +649% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +9 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.