Anchor DLC purchases to a base game instead of a parent purchase
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
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>
This commit is contained in:
@@ -44,7 +44,7 @@ docs/ — Additional documentation
|
||||
|
||||
- **Game** — `name`, `platform` (FK), `status` (u/p/f/r/a), `mastered`, `playtime` (DurationField updated via signal), `year_released`, `sort_name`, `wikidata`
|
||||
- **Platform** — `name`, `group`, `icon` (slug, auto-generated from name)
|
||||
- **Purchase** — ownership type, prices, currency conversion (`converted_price`, `price_per_game` is a `GeneratedField`), links to Game via M2M. `num_purchases` counts linked games. DLC/SeasonPass/BattlePass must have a `related_purchase`
|
||||
- **Purchase** — ownership type, prices, currency conversion (`converted_price`, `price_per_game` is a `GeneratedField`), links to Game via M2M. `num_purchases` counts linked games. DLC/SeasonPass/BattlePass must have a `related_game` (the base Game the add-on belongs to; reverse accessor `game.addon_purchases`)
|
||||
- **Session** — `timestamp_start`/`timestamp_end`, `duration_manual`, `device` (FK), `note`, `emulated`. `duration_calculated` and `duration_total` are `GeneratedField`s (cannot be written directly)
|
||||
- **Device** — `name`, `type` (PC/Console/Handheld/Mobile/SBC/Unknown)
|
||||
- **PlayEvent** — marks when a game was started/finished (separate from Sessions), `days_to_finish` is a `GeneratedField`
|
||||
|
||||
Reference in New Issue
Block a user