feat: use django-objects-actions
This commit is contained in:
@@ -1,4 +1,9 @@
|
|||||||
from django.contrib import admin, messages
|
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
|
from submissions.tasks import sync_event_game_scopes_task
|
||||||
|
|
||||||
@@ -19,17 +24,22 @@ class GameAdmin(admin.ModelAdmin):
|
|||||||
|
|
||||||
|
|
||||||
@admin.register(EventGame)
|
@admin.register(EventGame)
|
||||||
class EventGameAdmin(admin.ModelAdmin):
|
class EventGameAdmin(DjangoObjectActions, admin.ModelAdmin):
|
||||||
list_display = ["game", "event", "enabled", "has_apibot_token"]
|
list_display = ["game", "event", "enabled", "has_apibot_token"]
|
||||||
list_filter = ["event", "enabled"]
|
list_filter = ["event", "enabled"]
|
||||||
search_fields = ["game__name", "event__name"]
|
search_fields = ["game__name", "event__name"]
|
||||||
actions = ["sync_scopes"]
|
actions = ["sync_scopes"]
|
||||||
|
change_actions = ["sync_scopes"]
|
||||||
|
|
||||||
@admin.display(description="AAndT token", boolean=True)
|
@admin.display(description="AAndT token", boolean=True)
|
||||||
def has_apibot_token(self, obj):
|
def has_apibot_token(self, obj):
|
||||||
return bool(obj.apibot_token)
|
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):
|
def sync_scopes(self, request, queryset):
|
||||||
tokened = queryset.exclude(apibot_token__isnull=True).exclude(apibot_token="")
|
tokened = queryset.exclude(apibot_token__isnull=True).exclude(apibot_token="")
|
||||||
skipped = queryset.count() - tokened.count()
|
skipped = queryset.count() - tokened.count()
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
from django_object_actions import (
|
||||||
|
DjangoObjectActions,
|
||||||
|
action,
|
||||||
|
takes_instance_or_queryset,
|
||||||
|
)
|
||||||
from market.models import Market, MarketOption, UserBet, UserPointChange
|
from market.models import Market, MarketOption, UserBet, UserPointChange
|
||||||
|
|
||||||
|
|
||||||
@@ -9,7 +14,7 @@ class MarketOptionInline(admin.TabularInline):
|
|||||||
|
|
||||||
|
|
||||||
@admin.register(Market)
|
@admin.register(Market)
|
||||||
class MarketAdmin(admin.ModelAdmin):
|
class MarketAdmin(DjangoObjectActions, admin.ModelAdmin):
|
||||||
list_display = ["title", "status", "end_date", "created_by", "created_at"]
|
list_display = ["title", "status", "end_date", "created_by", "created_at"]
|
||||||
list_filter = ["status", "created_at"]
|
list_filter = ["status", "created_at"]
|
||||||
search_fields = ["uuid", "title"]
|
search_fields = ["uuid", "title"]
|
||||||
@@ -39,22 +44,25 @@ class MarketAdmin(admin.ModelAdmin):
|
|||||||
obj.created_by = request.user
|
obj.created_by = request.user
|
||||||
super().save_model(request, obj, form, change)
|
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):
|
def publish_markets(self, request, queryset):
|
||||||
updated = queryset.filter(status=Market.Status.DRAFT).update(
|
updated = queryset.filter(status=Market.Status.DRAFT).update(
|
||||||
status=Market.Status.OPEN
|
status=Market.Status.OPEN
|
||||||
)
|
)
|
||||||
self.message_user(request, f"Published {updated} market(s).")
|
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):
|
def close_markets(self, request, queryset):
|
||||||
updated = queryset.filter(status=Market.Status.OPEN).update(
|
updated = queryset.filter(status=Market.Status.OPEN).update(
|
||||||
status=Market.Status.CLOSED
|
status=Market.Status.CLOSED
|
||||||
)
|
)
|
||||||
self.message_user(request, f"Closed {updated} market(s).")
|
self.message_user(request, f"Closed {updated} market(s).")
|
||||||
|
|
||||||
actions = ["publish_markets", "close_markets"]
|
|
||||||
|
|
||||||
|
|
||||||
@admin.register(MarketOption)
|
@admin.register(MarketOption)
|
||||||
class MarketOptionAdmin(admin.ModelAdmin):
|
class MarketOptionAdmin(admin.ModelAdmin):
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
from django.contrib import admin
|
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 noita.services.objectives import parse_objectives_and_store
|
||||||
from .models import LogfileSubmission, Objectiv, ObjectivPoint, DeathCounter
|
from .models import LogfileSubmission, Objectiv, ObjectivPoint, DeathCounter
|
||||||
|
|
||||||
|
|
||||||
@admin.register(LogfileSubmission)
|
@admin.register(LogfileSubmission)
|
||||||
class LogfileSubmissionAdmin(admin.ModelAdmin):
|
class LogfileSubmissionAdmin(DjangoObjectActions, admin.ModelAdmin):
|
||||||
list_display = (
|
list_display = (
|
||||||
"id",
|
"id",
|
||||||
"user",
|
"user",
|
||||||
@@ -26,7 +31,10 @@ class LogfileSubmissionAdmin(admin.ModelAdmin):
|
|||||||
)
|
)
|
||||||
|
|
||||||
actions = ["validate_submission"]
|
actions = ["validate_submission"]
|
||||||
|
change_actions = ["validate_submission"]
|
||||||
|
|
||||||
|
@action(label="Validate", description="Validate selected submissions")
|
||||||
|
@takes_instance_or_queryset
|
||||||
def validate_submission(self, request, queryset):
|
def validate_submission(self, request, queryset):
|
||||||
for logfile in queryset:
|
for logfile in queryset:
|
||||||
parse_objectives_and_store(logfile)
|
parse_objectives_and_store(logfile)
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.utils.html import format_html
|
from django.utils.html import format_html
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from django_object_actions import (
|
||||||
|
DjangoObjectActions,
|
||||||
|
action,
|
||||||
|
takes_instance_or_queryset,
|
||||||
|
)
|
||||||
from opus_magnum.models import (
|
from opus_magnum.models import (
|
||||||
SteamAPIKey,
|
SteamAPIKey,
|
||||||
SteamCollection,
|
SteamCollection,
|
||||||
@@ -185,7 +190,7 @@ class PuzzleResponseInline(admin.TabularInline):
|
|||||||
|
|
||||||
|
|
||||||
@admin.register(Submission)
|
@admin.register(Submission)
|
||||||
class SubmissionAdmin(admin.ModelAdmin):
|
class SubmissionAdmin(DjangoObjectActions, admin.ModelAdmin):
|
||||||
list_display = [
|
list_display = [
|
||||||
"id",
|
"id",
|
||||||
"user",
|
"user",
|
||||||
@@ -238,9 +243,11 @@ class SubmissionAdmin(admin.ModelAdmin):
|
|||||||
)
|
)
|
||||||
|
|
||||||
actions = ["mark_as_validated"]
|
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):
|
def mark_as_validated(self, request, queryset):
|
||||||
"""Mark selected submissions as validated"""
|
|
||||||
updated = 0
|
updated = 0
|
||||||
for submission in queryset:
|
for submission in queryset:
|
||||||
if not submission.is_validated:
|
if not submission.is_validated:
|
||||||
@@ -254,11 +261,9 @@ class SubmissionAdmin(admin.ModelAdmin):
|
|||||||
|
|
||||||
self.message_user(request, f"{updated} submissions marked as validated.")
|
self.message_user(request, f"{updated} submissions marked as validated.")
|
||||||
|
|
||||||
mark_as_validated.short_description = "Mark selected submissions as validated"
|
|
||||||
|
|
||||||
|
|
||||||
@admin.register(PuzzleResponse)
|
@admin.register(PuzzleResponse)
|
||||||
class PuzzleResponseAdmin(admin.ModelAdmin):
|
class PuzzleResponseAdmin(DjangoObjectActions, admin.ModelAdmin):
|
||||||
list_display = [
|
list_display = [
|
||||||
"puzzle_name",
|
"puzzle_name",
|
||||||
"submission",
|
"submission",
|
||||||
@@ -314,22 +319,22 @@ class PuzzleResponseAdmin(admin.ModelAdmin):
|
|||||||
)
|
)
|
||||||
|
|
||||||
actions = ["mark_for_validation", "clear_validation_flag"]
|
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):
|
def mark_for_validation(self, request, queryset):
|
||||||
"""Mark selected responses as needing validation"""
|
|
||||||
updated = queryset.update(needs_manual_validation=True)
|
updated = queryset.update(needs_manual_validation=True)
|
||||||
self.message_user(request, f"{updated} responses marked for validation.")
|
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):
|
def clear_validation_flag(self, request, queryset):
|
||||||
"""Clear validation flag for selected responses"""
|
|
||||||
updated = queryset.update(needs_manual_validation=False)
|
updated = queryset.update(needs_manual_validation=False)
|
||||||
self.message_user(
|
self.message_user(
|
||||||
request, f"{updated} responses cleared from validation queue."
|
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)
|
@admin.register(SubmissionFile)
|
||||||
class SubmissionFileAdmin(admin.ModelAdmin):
|
class SubmissionFileAdmin(admin.ModelAdmin):
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ INSTALLED_APPS = [
|
|||||||
"django_vite",
|
"django_vite",
|
||||||
"django_rq",
|
"django_rq",
|
||||||
"django_tasks_rq",
|
"django_tasks_rq",
|
||||||
|
"django_object_actions",
|
||||||
"accounts",
|
"accounts",
|
||||||
"events",
|
"events",
|
||||||
"animations",
|
"animations",
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ dependencies = [
|
|||||||
"django-rq",
|
"django-rq",
|
||||||
"django-tasks-rq",
|
"django-tasks-rq",
|
||||||
"httpx>=0.28.1",
|
"httpx>=0.28.1",
|
||||||
|
"django-object-actions>=5.1.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[dependency-groups]
|
[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" },
|
{ 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]]
|
[[package]]
|
||||||
name = "django-redis"
|
name = "django-redis"
|
||||||
version = "6.0.0"
|
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 = "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", version = "6.0.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" },
|
||||||
{ name = "django-channels" },
|
{ name = "django-channels" },
|
||||||
|
{ name = "django-object-actions" },
|
||||||
{ name = "django-redis" },
|
{ name = "django-redis" },
|
||||||
{ name = "django-rq" },
|
{ name = "django-rq" },
|
||||||
{ name = "django-shinobi" },
|
{ name = "django-shinobi" },
|
||||||
@@ -1666,6 +1676,7 @@ requires-dist = [
|
|||||||
{ name = "daphne" },
|
{ name = "daphne" },
|
||||||
{ name = "django" },
|
{ name = "django" },
|
||||||
{ name = "django-channels" },
|
{ name = "django-channels" },
|
||||||
|
{ name = "django-object-actions", specifier = ">=5.1.2" },
|
||||||
{ name = "django-redis" },
|
{ name = "django-redis" },
|
||||||
{ name = "django-rq" },
|
{ name = "django-rq" },
|
||||||
{ name = "django-shinobi" },
|
{ name = "django-shinobi" },
|
||||||
|
|||||||
Reference in New Issue
Block a user