feat: use django-objects-actions
This commit is contained in:
@@ -1,4 +1,9 @@
|
||||
from django.contrib import admin, messages
|
||||
from django_object_actions import (
|
||||
DjangoObjectActions,
|
||||
action,
|
||||
takes_instance_or_queryset,
|
||||
)
|
||||
|
||||
from submissions.tasks import sync_event_game_scopes_task
|
||||
|
||||
@@ -19,17 +24,22 @@ class GameAdmin(admin.ModelAdmin):
|
||||
|
||||
|
||||
@admin.register(EventGame)
|
||||
class EventGameAdmin(admin.ModelAdmin):
|
||||
class EventGameAdmin(DjangoObjectActions, admin.ModelAdmin):
|
||||
list_display = ["game", "event", "enabled", "has_apibot_token"]
|
||||
list_filter = ["event", "enabled"]
|
||||
search_fields = ["game__name", "event__name"]
|
||||
actions = ["sync_scopes"]
|
||||
change_actions = ["sync_scopes"]
|
||||
|
||||
@admin.display(description="AAndT token", boolean=True)
|
||||
def has_apibot_token(self, obj):
|
||||
return bool(obj.apibot_token)
|
||||
|
||||
@admin.action(description="Sync scopes from AAndT for selected EventGames")
|
||||
@action(
|
||||
label="Sync scopes",
|
||||
description="Sync scopes from AAndT for selected EventGames",
|
||||
)
|
||||
@takes_instance_or_queryset
|
||||
def sync_scopes(self, request, queryset):
|
||||
tokened = queryset.exclude(apibot_token__isnull=True).exclude(apibot_token="")
|
||||
skipped = queryset.count() - tokened.count()
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
from django.contrib import admin
|
||||
from django_object_actions import (
|
||||
DjangoObjectActions,
|
||||
action,
|
||||
takes_instance_or_queryset,
|
||||
)
|
||||
from market.models import Market, MarketOption, UserBet, UserPointChange
|
||||
|
||||
|
||||
@@ -9,7 +14,7 @@ class MarketOptionInline(admin.TabularInline):
|
||||
|
||||
|
||||
@admin.register(Market)
|
||||
class MarketAdmin(admin.ModelAdmin):
|
||||
class MarketAdmin(DjangoObjectActions, admin.ModelAdmin):
|
||||
list_display = ["title", "status", "end_date", "created_by", "created_at"]
|
||||
list_filter = ["status", "created_at"]
|
||||
search_fields = ["uuid", "title"]
|
||||
@@ -39,22 +44,25 @@ class MarketAdmin(admin.ModelAdmin):
|
||||
obj.created_by = request.user
|
||||
super().save_model(request, obj, form, change)
|
||||
|
||||
@admin.action(description="Publish selected draft markets")
|
||||
actions = ["publish_markets", "close_markets"]
|
||||
change_actions = ["publish_markets", "close_markets"]
|
||||
|
||||
@action(label="Publish", description="Publish selected draft markets")
|
||||
@takes_instance_or_queryset
|
||||
def publish_markets(self, request, queryset):
|
||||
updated = queryset.filter(status=Market.Status.DRAFT).update(
|
||||
status=Market.Status.OPEN
|
||||
)
|
||||
self.message_user(request, f"Published {updated} market(s).")
|
||||
|
||||
@admin.action(description="Close selected markets")
|
||||
@action(label="Close", description="Close selected markets")
|
||||
@takes_instance_or_queryset
|
||||
def close_markets(self, request, queryset):
|
||||
updated = queryset.filter(status=Market.Status.OPEN).update(
|
||||
status=Market.Status.CLOSED
|
||||
)
|
||||
self.message_user(request, f"Closed {updated} market(s).")
|
||||
|
||||
actions = ["publish_markets", "close_markets"]
|
||||
|
||||
|
||||
@admin.register(MarketOption)
|
||||
class MarketOptionAdmin(admin.ModelAdmin):
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
from django.contrib import admin
|
||||
from django_object_actions import (
|
||||
DjangoObjectActions,
|
||||
action,
|
||||
takes_instance_or_queryset,
|
||||
)
|
||||
|
||||
from noita.services.objectives import parse_objectives_and_store
|
||||
from .models import LogfileSubmission, Objectiv, ObjectivPoint, DeathCounter
|
||||
|
||||
|
||||
@admin.register(LogfileSubmission)
|
||||
class LogfileSubmissionAdmin(admin.ModelAdmin):
|
||||
class LogfileSubmissionAdmin(DjangoObjectActions, admin.ModelAdmin):
|
||||
list_display = (
|
||||
"id",
|
||||
"user",
|
||||
@@ -26,7 +31,10 @@ class LogfileSubmissionAdmin(admin.ModelAdmin):
|
||||
)
|
||||
|
||||
actions = ["validate_submission"]
|
||||
change_actions = ["validate_submission"]
|
||||
|
||||
@action(label="Validate", description="Validate selected submissions")
|
||||
@takes_instance_or_queryset
|
||||
def validate_submission(self, request, queryset):
|
||||
for logfile in queryset:
|
||||
parse_objectives_and_store(logfile)
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
from django.contrib import admin
|
||||
from django.utils.html import format_html
|
||||
from django.utils import timezone
|
||||
from django_object_actions import (
|
||||
DjangoObjectActions,
|
||||
action,
|
||||
takes_instance_or_queryset,
|
||||
)
|
||||
from opus_magnum.models import (
|
||||
SteamAPIKey,
|
||||
SteamCollection,
|
||||
@@ -185,7 +190,7 @@ class PuzzleResponseInline(admin.TabularInline):
|
||||
|
||||
|
||||
@admin.register(Submission)
|
||||
class SubmissionAdmin(admin.ModelAdmin):
|
||||
class SubmissionAdmin(DjangoObjectActions, admin.ModelAdmin):
|
||||
list_display = [
|
||||
"id",
|
||||
"user",
|
||||
@@ -238,9 +243,11 @@ class SubmissionAdmin(admin.ModelAdmin):
|
||||
)
|
||||
|
||||
actions = ["mark_as_validated"]
|
||||
change_actions = ["mark_as_validated"]
|
||||
|
||||
@action(label="Validate", description="Mark selected submissions as validated")
|
||||
@takes_instance_or_queryset
|
||||
def mark_as_validated(self, request, queryset):
|
||||
"""Mark selected submissions as validated"""
|
||||
updated = 0
|
||||
for submission in queryset:
|
||||
if not submission.is_validated:
|
||||
@@ -254,11 +261,9 @@ class SubmissionAdmin(admin.ModelAdmin):
|
||||
|
||||
self.message_user(request, f"{updated} submissions marked as validated.")
|
||||
|
||||
mark_as_validated.short_description = "Mark selected submissions as validated"
|
||||
|
||||
|
||||
@admin.register(PuzzleResponse)
|
||||
class PuzzleResponseAdmin(admin.ModelAdmin):
|
||||
class PuzzleResponseAdmin(DjangoObjectActions, admin.ModelAdmin):
|
||||
list_display = [
|
||||
"puzzle_name",
|
||||
"submission",
|
||||
@@ -314,22 +319,22 @@ class PuzzleResponseAdmin(admin.ModelAdmin):
|
||||
)
|
||||
|
||||
actions = ["mark_for_validation", "clear_validation_flag"]
|
||||
change_actions = ["mark_for_validation", "clear_validation_flag"]
|
||||
|
||||
@action(label="Mark for validation", description="Mark as needing validation")
|
||||
@takes_instance_or_queryset
|
||||
def mark_for_validation(self, request, queryset):
|
||||
"""Mark selected responses as needing validation"""
|
||||
updated = queryset.update(needs_manual_validation=True)
|
||||
self.message_user(request, f"{updated} responses marked for validation.")
|
||||
|
||||
@action(label="Clear validation flag", description="Clear validation flag")
|
||||
@takes_instance_or_queryset
|
||||
def clear_validation_flag(self, request, queryset):
|
||||
"""Clear validation flag for selected responses"""
|
||||
updated = queryset.update(needs_manual_validation=False)
|
||||
self.message_user(
|
||||
request, f"{updated} responses cleared from validation queue."
|
||||
)
|
||||
|
||||
mark_for_validation.short_description = "Mark as needing validation"
|
||||
clear_validation_flag.short_description = "Clear validation flag"
|
||||
|
||||
|
||||
@admin.register(SubmissionFile)
|
||||
class SubmissionFileAdmin(admin.ModelAdmin):
|
||||
|
||||
@@ -45,6 +45,7 @@ INSTALLED_APPS = [
|
||||
"django_vite",
|
||||
"django_rq",
|
||||
"django_tasks_rq",
|
||||
"django_object_actions",
|
||||
"accounts",
|
||||
"events",
|
||||
"animations",
|
||||
|
||||
@@ -25,6 +25,7 @@ dependencies = [
|
||||
"django-rq",
|
||||
"django-tasks-rq",
|
||||
"httpx>=0.28.1",
|
||||
"django-object-actions>=5.1.2",
|
||||
]
|
||||
|
||||
[dependency-groups]
|
||||
|
||||
@@ -677,6 +677,15 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/64/96/d967ca440d6a8e3861120f51985d8e5aec79b9a8bdda16041206adfe7adc/django_extensions-4.1-py3-none-any.whl", hash = "sha256:0699a7af28f2523bf8db309a80278519362cd4b6e1fd0a8cd4bf063e1e023336", size = 232980, upload-time = "2025-04-11T01:15:37.701Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "django-object-actions"
|
||||
version = "5.1.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c4/2f/99e8fa3d117becebfbe46d54d0b85d81475b6375b85507907a7aaf1d5d2b/django_object_actions-5.1.2.tar.gz", hash = "sha256:a11ac544e5beb6b309a50e184a2086e1e18f6469704d9609bbe083a8972a2245", size = 19048, upload-time = "2026-05-28T05:48:29.88Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/37/23/c5743780fc68433f244fba86cd64b513b9d6a9491714ac700a4654b5e00f/django_object_actions-5.1.2-py3-none-any.whl", hash = "sha256:366dcd5ccfb3ef6a16ce4c147be8df2a35b52d637eb36fb9c558e28419ae4038", size = 16900, upload-time = "2026-05-28T05:48:28.56Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "django-redis"
|
||||
version = "6.0.0"
|
||||
@@ -1626,6 +1635,7 @@ dependencies = [
|
||||
{ name = "django", version = "5.2.14", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" },
|
||||
{ name = "django", version = "6.0.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" },
|
||||
{ name = "django-channels" },
|
||||
{ name = "django-object-actions" },
|
||||
{ name = "django-redis" },
|
||||
{ name = "django-rq" },
|
||||
{ name = "django-shinobi" },
|
||||
@@ -1666,6 +1676,7 @@ requires-dist = [
|
||||
{ name = "daphne" },
|
||||
{ name = "django" },
|
||||
{ name = "django-channels" },
|
||||
{ name = "django-object-actions", specifier = ">=5.1.2" },
|
||||
{ name = "django-redis" },
|
||||
{ name = "django-rq" },
|
||||
{ name = "django-shinobi" },
|
||||
|
||||
Reference in New Issue
Block a user