dcfea202ce
Django CI/CD / test (push) Successful in 3m35s
Staging deployment / deploy (push) Successful in 1m24s
Staging deployment / comment (push) Has been skipped
Staging deployment / teardown (push) Has been skipped
Django CI/CD / build-and-push (push) Has been skipped
Add-on purchases (DLC, Season Pass, Battle Pass) previously linked to a parent *purchase* via the `related_purchase` self-FK. When the base game was bought inside a multi-game purchase (e.g. a bundle), there was no per-game purchase to point at — only the whole bundle. Replace it with a `related_game` FK (Game -> Game): an add-on belongs to a *game*, which is unambiguous regardless of how the base game was bought. - models: drop `related_purchase`; add `related_game` (SET_NULL, related_name="addon_purchases"); require it for non-GAME types in `save()`. - forms: replace the parent-purchase picker with a flat `related_game` game search (reusing SearchSelectWidget/_game_options); drop the now unused related_purchase_queryset/RelatedPurchaseChoiceField. - views/urls: remove the obsolete related_purchase_by_game endpoint. - add_purchase.js: drop the parent-dropdown refetch; keep platform auto-fill; retarget the type toggle to #id_related_game. - migration 0020: add -> backfill (related_game = parent's first game by sort_name) -> remove related_purchase. - tests: model validation unit tests + an e2e test for the flat picker. related_game is deliberately game->game so it can later be synced from IGDB's parent_game without schema changes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
178 lines
5.3 KiB
Python
178 lines
5.3 KiB
Python
from django.urls import path
|
|
|
|
from games.views import (
|
|
device,
|
|
filter_presets,
|
|
game,
|
|
general,
|
|
platform,
|
|
playevent,
|
|
purchase,
|
|
session,
|
|
statuschange,
|
|
)
|
|
|
|
app_name = "games"
|
|
|
|
urlpatterns = [
|
|
path("", general.index, name="index"),
|
|
path("device/add", device.add_device, name="add_device"),
|
|
path("device/delete/<int:device_id>", device.delete_device, name="delete_device"),
|
|
path("device/edit/<int:device_id>", device.edit_device, name="edit_device"),
|
|
path("device/list", device.list_devices, name="list_devices"),
|
|
path("game/add", game.add_game, name="add_game"),
|
|
path("game/<int:game_id>/edit", game.edit_game, name="edit_game"),
|
|
path("game/<int:game_id>/view", game.view_game, name="view_game"),
|
|
path(
|
|
"game/<int:game_id>/delete/confirm",
|
|
game.delete_game_confirmation,
|
|
name="delete_game_confirmation",
|
|
),
|
|
path("game/<int:game_id>/delete", game.delete_game, name="delete_game"),
|
|
path("game/list", game.list_games, name="list_games"),
|
|
path("platform/add", platform.add_platform, name="add_platform"),
|
|
path(
|
|
"platform/<int:platform_id>/edit",
|
|
platform.edit_platform,
|
|
name="edit_platform",
|
|
),
|
|
path(
|
|
"platform/<int:platform_id>/delete",
|
|
platform.delete_platform,
|
|
name="delete_platform",
|
|
),
|
|
path("platform/list", platform.list_platforms, name="list_platforms"),
|
|
path("playevent/list", playevent.list_playevents, name="list_playevents"),
|
|
path("playevent/add", playevent.add_playevent, name="add_playevent"),
|
|
path(
|
|
"playevent/add/for-game/<int:game_id>",
|
|
playevent.add_playevent,
|
|
name="add_playevent_for_game",
|
|
),
|
|
path(
|
|
"playevent/edit/<int:playevent_id>",
|
|
playevent.edit_playevent,
|
|
name="edit_playevent",
|
|
),
|
|
path(
|
|
"playevent/delete/<int:playevent_id>",
|
|
playevent.delete_playevent,
|
|
name="delete_playevent",
|
|
),
|
|
path("purchase/add", purchase.add_purchase, name="add_purchase"),
|
|
path(
|
|
"purchase/add/for-game/<int:game_id>",
|
|
purchase.add_purchase,
|
|
name="add_purchase_for_game",
|
|
),
|
|
path(
|
|
"purchase/<int:purchase_id>/edit",
|
|
purchase.edit_purchase,
|
|
name="edit_purchase",
|
|
),
|
|
path(
|
|
"purchase/<int:purchase_id>/drop",
|
|
purchase.drop_purchase,
|
|
name="drop_purchase",
|
|
),
|
|
path(
|
|
"purchase/<int:purchase_id>/delete",
|
|
purchase.delete_purchase,
|
|
name="delete_purchase",
|
|
),
|
|
path(
|
|
"purchase/<int:purchase_id>/view",
|
|
purchase.view_purchase,
|
|
name="view_purchase",
|
|
),
|
|
path(
|
|
"purchase/<int:purchase_id>/finish",
|
|
purchase.finish_purchase,
|
|
name="finish_purchase",
|
|
),
|
|
path(
|
|
"purchase/list",
|
|
purchase.list_purchases,
|
|
name="list_purchases",
|
|
),
|
|
path(
|
|
"purchase/<int:purchase_id>/refund/confirm",
|
|
purchase.refund_purchase_confirmation,
|
|
name="refund_purchase_confirmation",
|
|
),
|
|
path(
|
|
"purchase/<int:purchase_id>/refund",
|
|
purchase.refund_purchase,
|
|
name="refund_purchase",
|
|
),
|
|
path("session/add", session.add_session, name="add_session"),
|
|
path(
|
|
"session/add/for-game/<int:game_id>",
|
|
session.add_session,
|
|
name="add_session_for_game",
|
|
),
|
|
path(
|
|
"session/add/from-game/<int:session_id>",
|
|
session.new_session_from_existing_session,
|
|
name="view_game_start_session_from_session",
|
|
),
|
|
path(
|
|
"session/add/from-list/<int:session_id>",
|
|
session.new_session_from_existing_session,
|
|
name="list_sessions_start_session_from_session",
|
|
),
|
|
path("session/<int:session_id>/edit", session.edit_session, name="edit_session"),
|
|
path(
|
|
"session/<int:session_id>/delete",
|
|
session.delete_session,
|
|
name="delete_session",
|
|
),
|
|
path(
|
|
"session/end/from-game/<int:session_id>",
|
|
session.end_session,
|
|
name="view_game_end_session",
|
|
),
|
|
path(
|
|
"session/end/from-list/<int:session_id>",
|
|
session.end_session,
|
|
name="list_sessions_end_session",
|
|
),
|
|
path("session/list", session.list_sessions, name="list_sessions"),
|
|
path("session/search", session.search_sessions, name="search_sessions"),
|
|
path(
|
|
"statuschange/add",
|
|
statuschange.add_statuschange,
|
|
name="add_statuschange",
|
|
),
|
|
path(
|
|
"statuschange/edit/<int:statuschange_id>",
|
|
statuschange.edit_statuschange,
|
|
name="edit_statuschange",
|
|
),
|
|
path(
|
|
"statuschange/delete/<int:pk>",
|
|
statuschange.delete_statuschange,
|
|
name="delete_statuschange",
|
|
),
|
|
path(
|
|
"statuschange/list",
|
|
statuschange.list_statuschanges,
|
|
name="list_statuschanges",
|
|
),
|
|
path("stats/", general.stats_alltime, name="stats_alltime"),
|
|
path("stats/<int:year>", general.stats, name="stats_by_year"),
|
|
# Filter presets
|
|
path("filter/presets/list", filter_presets.list_presets, name="list_presets"),
|
|
path("filter/presets/save", filter_presets.save_preset, name="save_preset"),
|
|
path(
|
|
"filter/presets/<int:preset_id>/delete",
|
|
filter_presets.delete_preset,
|
|
name="delete_preset",
|
|
),
|
|
path(
|
|
"filter/presets/<int:preset_id>/load",
|
|
filter_presets.load_preset,
|
|
name="load_preset",
|
|
),
|
|
]
|