feat(admin): add unfold admin panel
This commit is contained in:
@@ -22,6 +22,20 @@ GET /api/jobs/stats/
|
||||
POST /api/jobs/{id}/retry/
|
||||
```
|
||||
|
||||
## Admin
|
||||
|
||||
The project uses `django-unfold` for the Django admin UI.
|
||||
|
||||
```text
|
||||
http://localhost:8000/admin/
|
||||
```
|
||||
|
||||
Create a user:
|
||||
|
||||
```powershell
|
||||
docker compose exec backend python manage.py createsuperuser
|
||||
```
|
||||
|
||||
## Worker
|
||||
|
||||
```powershell
|
||||
|
||||
@@ -12,6 +12,7 @@ DEBUG = os.getenv("DEBUG", "true").lower() in {"1", "true", "yes"}
|
||||
ALLOWED_HOSTS = [host.strip() for host in os.getenv("DJANGO_ALLOWED_HOSTS", "localhost,127.0.0.1,0.0.0.0").split(",")]
|
||||
|
||||
INSTALLED_APPS = [
|
||||
"unfold",
|
||||
"django.contrib.admin",
|
||||
"django.contrib.auth",
|
||||
"django.contrib.contenttypes",
|
||||
@@ -113,6 +114,12 @@ SPECTACULAR_SETTINGS = {
|
||||
"SERVE_INCLUDE_SCHEMA": False,
|
||||
}
|
||||
|
||||
UNFOLD = {
|
||||
"SITE_TITLE": "Minimal Job Queue Admin",
|
||||
"SITE_HEADER": "Minimal Job Queue",
|
||||
"SITE_SUBHEADER": "Jobs, attempts, leases, and events",
|
||||
}
|
||||
|
||||
JOB_WORKER_THREADS = int(os.getenv("JOB_WORKER_THREADS", "4"))
|
||||
JOB_WORKER_POLL_INTERVAL_MS = int(os.getenv("JOB_WORKER_POLL_INTERVAL_MS", "500"))
|
||||
JOB_WORKER_LEASE_SECONDS = int(os.getenv("JOB_WORKER_LEASE_SECONDS", "30"))
|
||||
|
||||
@@ -1,18 +1,34 @@
|
||||
from django.contrib import admin
|
||||
from unfold.admin import ModelAdmin
|
||||
|
||||
from jobs.models import Job, JobEvent
|
||||
|
||||
|
||||
@admin.register(Job)
|
||||
class JobAdmin(admin.ModelAdmin):
|
||||
class JobAdmin(ModelAdmin):
|
||||
list_display = ("id", "type", "status", "priority", "attempts", "max_attempts", "locked_by", "available_at")
|
||||
list_filter = ("status", "type")
|
||||
search_fields = ("id", "type", "idempotency_key", "locked_by")
|
||||
readonly_fields = ("created_at", "updated_at", "finished_at")
|
||||
readonly_fields = (
|
||||
"id",
|
||||
"attempts",
|
||||
"locked_by",
|
||||
"locked_until",
|
||||
"last_error",
|
||||
"result",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"finished_at",
|
||||
)
|
||||
ordering = ("-created_at",)
|
||||
list_per_page = 50
|
||||
|
||||
|
||||
@admin.register(JobEvent)
|
||||
class JobEventAdmin(admin.ModelAdmin):
|
||||
class JobEventAdmin(ModelAdmin):
|
||||
list_display = ("id", "job", "type", "attempt", "worker_id", "created_at")
|
||||
list_filter = ("type",)
|
||||
search_fields = ("job__id", "worker_id", "message")
|
||||
readonly_fields = ("job", "type", "attempt", "worker_id", "message", "data", "created_at")
|
||||
ordering = ("-id",)
|
||||
list_per_page = 100
|
||||
|
||||
@@ -4,6 +4,7 @@ django-cors-headers>=4.7,<5.0
|
||||
drf-spectacular>=0.28,<0.29
|
||||
python-dotenv>=1.1,<2.0
|
||||
psycopg[binary]>=3.2,<4.0
|
||||
django-unfold>=0.76,<1.0
|
||||
pytest>=8.0,<9.0
|
||||
pytest-django>=4.9,<5.0
|
||||
ruff>=0.15,<0.16
|
||||
|
||||
Reference in New Issue
Block a user