feat: add events app + "multi-tenants" aka multi-events
This commit is contained in:
@@ -1,28 +1,23 @@
|
||||
from django.contrib import admin
|
||||
|
||||
from .models import Game
|
||||
from .models import EventGame, Game
|
||||
|
||||
|
||||
def enable_games(modeladmin, request, queryset):
|
||||
updated = queryset.update(enabled=True)
|
||||
modeladmin.message_user(request, f"{updated} game(s) enabled successfully.")
|
||||
|
||||
|
||||
enable_games.short_description = "Enable selected games"
|
||||
|
||||
|
||||
def disable_games(modeladmin, request, queryset):
|
||||
updated = queryset.update(enabled=False)
|
||||
modeladmin.message_user(request, f"{updated} game(s) disabled successfully.")
|
||||
|
||||
|
||||
disable_games.short_description = "Disable selected games"
|
||||
class EventGameInline(admin.TabularInline):
|
||||
model = EventGame
|
||||
extra = 0
|
||||
|
||||
|
||||
@admin.register(Game)
|
||||
class GameAdmin(admin.ModelAdmin):
|
||||
list_display = ["name", "steam_app_id", "enabled", "updated_at"]
|
||||
list_filter = ["enabled"]
|
||||
list_display = ["name", "steam_app_id", "updated_at"]
|
||||
search_fields = ["name", "steam_app_id"]
|
||||
readonly_fields = ["created_at", "updated_at"]
|
||||
actions = [enable_games, disable_games]
|
||||
inlines = [EventGameInline]
|
||||
|
||||
|
||||
@admin.register(EventGame)
|
||||
class EventGameAdmin(admin.ModelAdmin):
|
||||
list_display = ["game", "event", "enabled"]
|
||||
list_filter = ["event", "enabled"]
|
||||
search_fields = ["game__name", "event__name"]
|
||||
|
||||
@@ -6,8 +6,14 @@ from .models import Game
|
||||
from .schemas import GameOut
|
||||
|
||||
router = Router()
|
||||
event_router = Router()
|
||||
|
||||
|
||||
@router.get("", response=List[GameOut])
|
||||
def list_games(request):
|
||||
return Game.objects.filter(enabled=True)
|
||||
return Game.objects.all()
|
||||
|
||||
|
||||
@event_router.get("/events/{event_path}/games", response=List[GameOut])
|
||||
def list_event_games(request, event_path: str):
|
||||
return Game.objects.enabled_for_event(request.event)
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
from functools import wraps
|
||||
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.shortcuts import get_object_or_404
|
||||
|
||||
from events.models import Event
|
||||
from .models import Game
|
||||
|
||||
|
||||
@@ -9,12 +11,15 @@ def require_game_enabled(steam_app_id: int):
|
||||
def decorator(view_func):
|
||||
@wraps(view_func)
|
||||
def wrapper(request, *args, **kwargs):
|
||||
try:
|
||||
game = Game.objects.get(steam_app_id=steam_app_id)
|
||||
except Game.DoesNotExist:
|
||||
raise PermissionDenied
|
||||
if not game.enabled:
|
||||
event = get_object_or_404(Event, path=kwargs.get("event_path"))
|
||||
|
||||
if (
|
||||
not Game.objects.enabled_for_event(event)
|
||||
.filter(steam_app_id=steam_app_id)
|
||||
.exists()
|
||||
):
|
||||
raise PermissionDenied
|
||||
|
||||
return view_func(request, *args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
# Generated by Django 6.0.5 on 2026-09-15 21:11
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("events", "0002_seed_polylan_43"),
|
||||
("games", "0004_game_image_alter_game_steam_app_id"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="EventGame",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("enabled", models.BooleanField(default=True)),
|
||||
(
|
||||
"event",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="event_games",
|
||||
to="events.event",
|
||||
),
|
||||
),
|
||||
(
|
||||
"game",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="event_games",
|
||||
to="games.game",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"constraints": [
|
||||
models.UniqueConstraint(
|
||||
fields=("event", "game"), name="unique_event_game"
|
||||
)
|
||||
],
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,16 @@
|
||||
# Generated by Django 6.0.5 on 2026-09-15 21:51
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("games", "0005_eventgame"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name="game",
|
||||
name="enabled",
|
||||
),
|
||||
]
|
||||
@@ -1,16 +1,24 @@
|
||||
from django.db import models
|
||||
|
||||
from events.models import Event
|
||||
|
||||
|
||||
class GameQuerySet(models.QuerySet):
|
||||
def enabled_for_event(self, event):
|
||||
return self.exclude(event_games__event=event, event_games__enabled=False)
|
||||
|
||||
|
||||
class Game(models.Model):
|
||||
steam_app_id = models.PositiveIntegerField(null=True, blank=True)
|
||||
name = models.CharField(max_length=255)
|
||||
path = models.CharField(max_length=100)
|
||||
image = models.URLField(null=True, blank=True)
|
||||
enabled = models.BooleanField(default=True)
|
||||
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
objects = models.Manager.from_queryset(GameQuerySet)()
|
||||
|
||||
class Meta:
|
||||
ordering = ["name"]
|
||||
|
||||
@@ -18,3 +26,28 @@ class Game(models.Model):
|
||||
if self.steam_app_id:
|
||||
return f"{self.name} ({self.steam_app_id})"
|
||||
return self.name
|
||||
|
||||
|
||||
class EventGame(models.Model):
|
||||
event = models.ForeignKey(
|
||||
Event,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="event_games",
|
||||
)
|
||||
game = models.ForeignKey(
|
||||
Game,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="event_games",
|
||||
)
|
||||
enabled = models.BooleanField(default=True)
|
||||
|
||||
class Meta:
|
||||
constraints = [
|
||||
models.UniqueConstraint(
|
||||
fields=["event", "game"],
|
||||
name="unique_event_game",
|
||||
),
|
||||
]
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"{self.game.name} @ {self.event.name} ({'enabled' if self.enabled else 'disabled'})"
|
||||
|
||||
Reference in New Issue
Block a user