Use .twitch_id instead of .id

This commit is contained in:
Joakim Hellsén 2026-01-07 20:55:04 +01:00
commit d63e20aebc
No known key found for this signature in database
11 changed files with 32 additions and 64 deletions

View file

@ -130,7 +130,7 @@
</thead> </thead>
<tbody> <tbody>
{% for drop in drops %} {% for drop in drops %}
<tr id="drop-{{ drop.drop.id }}"> <tr id="drop-{{ drop.drop.twitch_id }}">
<td> <td>
{% for benefit in drop.drop.benefits.all %} {% for benefit in drop.drop.benefits.all %}
{% if benefit.image_asset_url %} {% if benefit.image_asset_url %}

View file

@ -25,9 +25,9 @@
<select id="game" name="game"> <select id="game" name="game">
<option value="">All Games</option> <option value="">All Games</option>
{% for game in games %} {% for game in games %}
<option value="{{ game.id }}" <option value="{{ game.twitch_id }}"
{% if selected_game == game.id %}selected{% endif %}> {% if selected_game == game.twitch_id %}selected{% endif %}>
{{ game.display_name|default:game.name|default:game.slug|default:game.id }} {{ game.display_name|default:game.name|default:game.slug|default:game.twitch_id }}
</option> </option>
{% endfor %} {% endfor %}
</select> </select>
@ -80,7 +80,7 @@
<h2 style="margin: 0 0 0.5rem 0;"> <h2 style="margin: 0 0 0.5rem 0;">
<a id="game-link-{{ game_group.grouper.twitch_id }}" <a id="game-link-{{ game_group.grouper.twitch_id }}"
href="{% url 'twitch:game_detail' game_group.grouper.twitch_id %}" href="{% url 'twitch:game_detail' game_group.grouper.twitch_id %}"
style="text-decoration: none">{{ game_group.grouper.display_name|default:game_group.grouper.name|default:game_group.grouper.slug|default:game_group.grouper.id }}</a> style="text-decoration: none">{{ game_group.grouper.display_name|default:game_group.grouper.name|default:game_group.grouper.slug|default:game_group.grouper.twitch_id }}</a>
</h2> </h2>
{% comment %} Check if the owner exists and has a valid ID before creating the link {% endcomment %} {% comment %} Check if the owner exists and has a valid ID before creating the link {% endcomment %}
{% if game_group.grouper.owner and game_group.grouper.owner.twitch_id %} {% if game_group.grouper.owner and game_group.grouper.owner.twitch_id %}

View file

@ -12,7 +12,7 @@
{% endif %} {% endif %}
<!-- Channel Info --> <!-- Channel Info -->
<p> <p>
<strong>Channel ID:</strong> {{ channel.id }} <strong>Channel ID:</strong> {{ channel.twitch_id }}
</p> </p>
<p> <p>
<strong>Added to database:</strong> <strong>Added to database:</strong>
@ -50,7 +50,7 @@
</td> </td>
<td> <td>
{% if campaign.game %} {% if campaign.game %}
<a href="{% url 'twitch:game_detail' campaign.game.id %}"> <a href="{% url 'twitch:game_detail' campaign.game.twitch_id %}">
{{ campaign.game.display_name|default:campaign.game.name }} {{ campaign.game.display_name|default:campaign.game.name }}
</a> </a>
{% else %} {% else %}
@ -94,7 +94,7 @@
</td> </td>
<td> <td>
{% if campaign.game %} {% if campaign.game %}
<a href="{% url 'twitch:game_detail' campaign.game.id %}"> <a href="{% url 'twitch:game_detail' campaign.game.twitch_id %}">
{{ campaign.game.display_name|default:campaign.game.name }} {{ campaign.game.display_name|default:campaign.game.name }}
</a> </a>
{% else %} {% else %}
@ -138,7 +138,7 @@
</td> </td>
<td> <td>
{% if campaign.game %} {% if campaign.game %}
<a href="{% url 'twitch:game_detail' campaign.game.id %}"> <a href="{% url 'twitch:game_detail' campaign.game.twitch_id %}">
{{ campaign.game.display_name|default:campaign.game.name }} {{ campaign.game.display_name|default:campaign.game.name }}
</a> </a>
{% else %} {% else %}

View file

@ -32,9 +32,9 @@
</thead> </thead>
<tbody> <tbody>
{% for channel in channels %} {% for channel in channels %}
<tr id="channel-row-{{ channel.id }}"> <tr id="channel-row-{{ channel.twitch_id }}">
<td> <td>
<a id="channel-link-{{ channel.id }}" <a id="channel-link-{{ channel.twitch_id }}"
href="{% url 'twitch:channel_detail' channel.twitch_id %}">{{ channel.display_name }}</a> href="{% url 'twitch:channel_detail' channel.twitch_id %}">{{ channel.display_name }}</a>
</td> </td>
<td>{{ channel.name }}</td> <td>{{ channel.name }}</td>

View file

@ -12,7 +12,7 @@
{% if games_without_owner %} {% if games_without_owner %}
<ul id="games-without-owner-list"> <ul id="games-without-owner-list">
{% for game in games_without_owner %} {% for game in games_without_owner %}
<li id="game-{{ game.id }}"> <li id="game-{{ game.twitch_id }}">
<a href="{% url 'twitch:game_detail' game.twitch_id %}">{{ game.display_name }}</a> (ID: {{ game.twitch_id }}) <a href="{% url 'twitch:game_detail' game.twitch_id %}">{{ game.display_name }}</a> (ID: {{ game.twitch_id }})
</li> </li>
{% endfor %} {% endfor %}
@ -45,7 +45,7 @@
{# A benefit is linked to a game via a drop and a campaign. #} {# A benefit is linked to a game via a drop and a campaign. #}
{# We use the 'with' tag to get the first drop for cleaner access. #} {# We use the 'with' tag to get the first drop for cleaner access. #}
{% with first_drop=b.drops.all.0 %} {% with first_drop=b.drops.all.0 %}
<li id="benefit-{{ b.id }}"> <li id="benefit-{{ b.twitch_id }}">
{{ b.name }} {{ b.name }}
{# Check if the relationship path to the game exists #} {# Check if the relationship path to the game exists #}
{% if first_drop and first_drop.campaign and first_drop.campaign.game %} {% if first_drop and first_drop.campaign and first_drop.campaign.game %}
@ -124,7 +124,7 @@
{% for row in duplicate_name_campaigns %} {% for row in duplicate_name_campaigns %}
<tr> <tr>
<td> <td>
<a href="{% url 'twitch:game_detail' row.game_id %}">{{ row.game__display_name }}</a> <a href="{% url 'twitch:game_detail' row.game__twitch_id %}">{{ row.game__display_name }}</a>
</td> </td>
<td>{{ row.name }}</td> <td>{{ row.name }}</td>
<td>{{ row.name_count }}</td> <td>{{ row.name_count }}</td>

View file

@ -16,7 +16,7 @@
<div style="display: flex; flex-wrap: wrap; gap: 0.25rem;"> <div style="display: flex; flex-wrap: wrap; gap: 0.25rem;">
{% for organization, games in games_by_org.items %} {% for organization, games in games_by_org.items %}
{% for item in games %} {% for item in games %}
<article id="game-{{ item.game.id }}" <article id="game-{{ item.game.twitch_id }}"
style="padding: 0.25rem; style="padding: 0.25rem;
border-radius: 8px; border-radius: 8px;
flex: 1 1 160px; flex: 1 1 160px;

View file

@ -10,10 +10,10 @@
</p> </p>
{% if games_by_org %} {% if games_by_org %}
{% for organization, games in games_by_org.items %} {% for organization, games in games_by_org.items %}
<h2 id="org-{{ organization.id }}">{{ organization.name }}</h2> <h2 id="org-{{ organization.twitch_id }}">{{ organization.name }}</h2>
<ul style="list-style: none; padding: 0; margin: 0;"> <ul style="list-style: none; padding: 0; margin: 0;">
{% for item in games %} {% for item in games %}
<li id="game-{{ item.game.id }}"> <li id="game-{{ item.game.twitch_id }}">
<a href="{% url 'twitch:game_detail' item.game.twitch_id %}">{{ item.game.display_name }}</a> <a href="{% url 'twitch:game_detail' item.game.twitch_id %}">{{ item.game.display_name }}</a>
</li> </li>
{% endfor %} {% endfor %}

View file

@ -7,7 +7,7 @@
{% if orgs %} {% if orgs %}
<ul id="org-list"> <ul id="org-list">
{% for organization in orgs %} {% for organization in orgs %}
<li id="org-{{ organization.id }}"> <li id="org-{{ organization.twitch_id }}">
<a href="{% url 'twitch:organization_detail' organization.twitch_id %}">{{ organization.name }}</a> <a href="{% url 'twitch:organization_detail' organization.twitch_id %}">{{ organization.name }}</a>
</li> </li>
{% endfor %} {% endfor %}

View file

@ -7,7 +7,7 @@
{% if user.is_authenticated %} {% if user.is_authenticated %}
<form id="notification-form" <form id="notification-form"
method="post" method="post"
action="{% url 'twitch:subscribe_org_notifications' org_id=organization.id %}"> action="{% url 'twitch:subscribe_org_notifications' org_id=organization.twitch_id %}">
{% csrf_token %} {% csrf_token %}
<div> <div>
<input type="checkbox" <input type="checkbox"
@ -30,7 +30,7 @@
{% endif %} {% endif %}
<ul id="games-list"> <ul id="games-list">
{% for game in games %} {% for game in games %}
<li id="game-{{ game.id }}"> <li id="game-{{ game.twitch_id }}">
<a href="{% url 'twitch:game_detail' game.twitch_id %}">{{ game }}</a> <a href="{% url 'twitch:game_detail' game.twitch_id %}">{{ game }}</a>
</li> </li>
{% endfor %} {% endfor %}

View file

@ -43,7 +43,7 @@
<ul id="drops-list"> <ul id="drops-list">
{% for drop in results.drops %} {% for drop in results.drops %}
<li id="drop-{{ drop.twitch_id }}"> <li id="drop-{{ drop.twitch_id }}">
<a href="{% url 'twitch:campaign_detail' drop.campaign.pk %}#drop-{{ drop.twitch_id }}">{{ drop.name }}</a> (in {{ drop.campaign.name }}) <a href="{% url 'twitch:campaign_detail' drop.campaign.twitch_id %}#drop-{{ drop.twitch_id }}">{{ drop.name }}</a> (in {{ drop.campaign.name }})
</li> </li>
{% endfor %} {% endfor %}
</ul> </ul>
@ -51,7 +51,11 @@
{% if results.benefits %} {% if results.benefits %}
<h2 id="benefits-header">Benefits</h2> <h2 id="benefits-header">Benefits</h2>
<ul id="benefits-list"> <ul id="benefits-list">
{% for benefit in results.benefits %}<li id="benefit-{{ benefit.twitch_id }}">{{ benefit.name }}</li>{% endfor %} {% for benefit in results.benefits %}
<li id="benefit-{{ benefit.twitch_id }}">
<a href="{% url 'twitch:campaign_detail' benefit.drops.first.campaign.twitch_id %}">{{ benefit.name }}</a>
</li>
{% endfor %}
</ul> </ul>
{% endif %} {% endif %}
{% endif %} {% endif %}

View file

@ -68,7 +68,9 @@ def search_view(request: HttpRequest) -> HttpResponse:
Q(name__istartswith=query) | Q(description__icontains=query), Q(name__istartswith=query) | Q(description__icontains=query),
).select_related("game") ).select_related("game")
results["drops"] = TimeBasedDrop.objects.filter(name__istartswith=query).select_related("campaign") results["drops"] = TimeBasedDrop.objects.filter(name__istartswith=query).select_related("campaign")
results["benefits"] = DropBenefit.objects.filter(name__istartswith=query) results["benefits"] = DropBenefit.objects.filter(name__istartswith=query).prefetch_related(
"drops__campaign",
)
else: else:
# SQLite-compatible text search using icontains # SQLite-compatible text search using icontains
results["organizations"] = Organization.objects.filter( results["organizations"] = Organization.objects.filter(
@ -85,7 +87,7 @@ def search_view(request: HttpRequest) -> HttpResponse:
).select_related("campaign") ).select_related("campaign")
results["benefits"] = DropBenefit.objects.filter( results["benefits"] = DropBenefit.objects.filter(
name__icontains=query, name__icontains=query,
) ).prefetch_related("drops__campaign")
return render( return render(
request, request,
@ -181,7 +183,7 @@ def drop_campaign_list_view(request: HttpRequest) -> HttpResponse:
queryset: QuerySet[DropCampaign] = DropCampaign.objects.all() queryset: QuerySet[DropCampaign] = DropCampaign.objects.all()
if game_filter: if game_filter:
queryset = queryset.filter(game__id=game_filter) queryset = queryset.filter(game__twitch_id=game_filter)
queryset = queryset.select_related("game__owner").order_by("-start_at") queryset = queryset.select_related("game__owner").order_by("-start_at")
@ -541,24 +543,6 @@ class GameDetailView(DetailView):
campaign for campaign in all_campaigns if campaign.end_at is not None and campaign.end_at < now campaign for campaign in all_campaigns if campaign.end_at is not None and campaign.end_at < now
] ]
# Build campaign data with sorted benefits
campaigns_with_benefits: list[dict[str, Any]] = []
for campaign in all_campaigns:
benefits_dict: dict[int, DropBenefit] = {}
for drop in campaign.time_based_drops.all(): # type: ignore[attr-defined]
for benefit in drop.benefits.all():
benefits_dict[benefit.id] = benefit
sorted_benefits = sorted(
benefits_dict.values(),
key=lambda b: b.name,
)
campaigns_with_benefits.append(
{
"campaign": campaign,
"sorted_benefits": sorted_benefits,
},
)
serialized_game: str = serialize( serialized_game: str = serialize(
"json", "json",
[game], [game],
@ -606,7 +590,6 @@ class GameDetailView(DetailView):
"active_campaigns": active_campaigns, "active_campaigns": active_campaigns,
"upcoming_campaigns": upcoming_campaigns, "upcoming_campaigns": upcoming_campaigns,
"expired_campaigns": expired_campaigns, "expired_campaigns": expired_campaigns,
"campaigns_with_benefits": campaigns_with_benefits,
"owner": game.owner, "owner": game.owner,
"now": now, "now": now,
"game_data": format_and_color_json(game_data[0]), "game_data": format_and_color_json(game_data[0]),
@ -732,7 +715,7 @@ def debug_view(request: HttpRequest) -> HttpResponse:
# We retrieve the game's name for user-friendly display. # We retrieve the game's name for user-friendly display.
duplicate_name_campaigns = ( duplicate_name_campaigns = (
DropCampaign.objects DropCampaign.objects
.values("game_id", "game__display_name", "name") .values("game__display_name", "name", "game__twitch_id")
.annotate(name_count=Count("twitch_id")) .annotate(name_count=Count("twitch_id"))
.filter(name_count__gt=1) .filter(name_count__gt=1)
.order_by("game__display_name", "name") .order_by("game__display_name", "name")
@ -931,24 +914,6 @@ class ChannelDetailView(DetailView):
campaign for campaign in all_campaigns if campaign.end_at is not None and campaign.end_at < now campaign for campaign in all_campaigns if campaign.end_at is not None and campaign.end_at < now
] ]
# Build campaign data with sorted benefits
campaigns_with_benefits = []
for campaign in all_campaigns:
benefits_dict: dict[int, DropBenefit] = {}
for drop in campaign.time_based_drops.all(): # type: ignore[attr-defined]
for benefit in drop.benefits.all():
benefits_dict[benefit.id] = benefit
sorted_benefits = sorted(
benefits_dict.values(),
key=lambda b: b.name,
)
campaigns_with_benefits.append(
{
"campaign": campaign,
"sorted_benefits": sorted_benefits,
},
)
serialized_channel = serialize( serialized_channel = serialize(
"json", "json",
[channel], [channel],
@ -987,7 +952,6 @@ class ChannelDetailView(DetailView):
"active_campaigns": active_campaigns, "active_campaigns": active_campaigns,
"upcoming_campaigns": upcoming_campaigns, "upcoming_campaigns": upcoming_campaigns,
"expired_campaigns": expired_campaigns, "expired_campaigns": expired_campaigns,
"campaigns_with_benefits": campaigns_with_benefits,
"now": now, "now": now,
"channel_data": format_and_color_json(channel_data[0]), "channel_data": format_and_color_json(channel_data[0]),
}, },