# django-management-ui

Run any Django management command from the admin panel. No models, no migrations — just install and go.

**[Documentation](https://mlopotkov.gitlab.io/django-management-ui/)**

The app introspects argparse definitions of your commands and dynamically builds forms with appropriate widgets: text inputs, checkboxes, dropdowns, number fields, file uploads for `Path` arguments.

## Features

- Automatic discovery of all registered management commands
- Dynamic form generation from argparse argument types
- File upload with temp file lifecycle for `Path` arguments (upload or enter path as text)
- Grouped display: command-specific args + collapsible BaseCommand options
- Output capture (stdout/stderr) with execution time
- Superuser-only access
- Appears on the Django Admin index page in the app list as "Commands" section
- Command blacklist to hide dangerous commands
- Configurable execution timeout (default 30s)
- Output truncation for large command outputs

## Quick start

### 1. Install

```bash
pip install django-management-ui
```

### 2. Add to INSTALLED_APPS

```python
INSTALLED_APPS = [
    ...
    "management_ui",
]
```

### 3. Add URL configuration

```python
# urls.py
from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path("admin/", include("management_ui.urls")),
    path("admin/", admin.site.urls),
]
```

That's it. Navigate to `/admin/commands/` to see all available commands.

## How it works

```
argparse introspection → ArgumentInfo → Django form field → execute command → CommandResult
```

1. **Discovery** — finds all registered management commands via `django.core.management.get_commands()`
2. **Introspection** — parses argparse `_actions` into `ArgumentInfo` dataclasses
3. **Form generation** — maps argument types to Django form fields:

| Argument type | Form field |
|---|---|
| `store_true` / `store_false` | `BooleanField` (checkbox) |
| `choices` | `ChoiceField` (dropdown) |
| `type=int` | `IntegerField` |
| `type=float` | `FloatField` |
| `type=Path` | `PathField` (file upload + text input toggle) |
| default / `type=str` | `CharField` |

4. **Execution** — runs command via `call_command()`, captures stdout/stderr, measures duration
5. **Result** — displays output with success/error styling

## Path argument support

When a command argument has `type=Path`, the form renders a dual-mode widget:

- **File upload mode** (default) — upload a file, it's saved to `/tmp/` with a unique name, path passed to command, temp file cleaned up after execution
- **Text path mode** — enter a server path as text (toggle via "or enter path as text" link)

## Requirements

- Python >= 3.11
- Django >= 4.2

## License

MIT
