Add game answer functionality with form and view for user responses
This commit is contained in:
parent
6dbb1a54e0
commit
d03d3b48d4
9 changed files with 97 additions and 12 deletions
|
@ -130,3 +130,7 @@ td.c, th.c {
|
|||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
table select {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
|
|
@ -39,3 +39,22 @@ class MusikGameForm(forms.ModelForm):
|
|||
kwargs["initial"].setdefault("players", players)
|
||||
super().__init__(*args, **kwargs)
|
||||
self.fields["players"].queryset = players
|
||||
|
||||
|
||||
class AnswerForm(forms.Form):
|
||||
def __init__(self, *args, **kwargs):
|
||||
game = kwargs.pop("game")
|
||||
user = kwargs.pop("user")
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
for music in game.musicgameorder_set.all():
|
||||
self.fields[f"answer-{music.order}"] = forms.ChoiceField(
|
||||
choices=[("", "")]
|
||||
+ list(game.players.all().values_list("id", "username")),
|
||||
required=False,
|
||||
label=music.order,
|
||||
initial=ma.answer.id
|
||||
if (ma := music.musicgameanswer_set.filter(player=user).first())
|
||||
and ma.answer
|
||||
else "",
|
||||
)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.3 on 2025-06-15 09:56
|
||||
# Generated by Django 5.2.3 on 2025-06-15 10:36
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
|
@ -24,7 +24,6 @@ class Migration(migrations.Migration):
|
|||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("order", models.PositiveIntegerField()),
|
||||
(
|
||||
"answer",
|
||||
models.ForeignKey(
|
||||
|
@ -37,7 +36,8 @@ class Migration(migrations.Migration):
|
|||
(
|
||||
"game",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE, to="game.musikgame"
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="game.musicgameorder",
|
||||
),
|
||||
),
|
||||
(
|
||||
|
@ -49,10 +49,10 @@ class Migration(migrations.Migration):
|
|||
),
|
||||
],
|
||||
options={
|
||||
"ordering": ["order"],
|
||||
"ordering": ["game"],
|
||||
"constraints": [
|
||||
models.UniqueConstraint(
|
||||
fields=("game", "player", "order"), name="unique_answer"
|
||||
fields=("game", "player"), name="unique_answer"
|
||||
)
|
||||
],
|
||||
},
|
||||
|
|
|
@ -114,17 +114,14 @@ class MusicGameOrder(models.Model):
|
|||
|
||||
|
||||
class MusicGameAnswer(models.Model):
|
||||
game = models.ForeignKey(MusikGame, on_delete=models.CASCADE)
|
||||
game = models.ForeignKey(MusicGameOrder, on_delete=models.CASCADE)
|
||||
player = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
order = models.PositiveIntegerField()
|
||||
answer = models.ForeignKey(
|
||||
User, on_delete=models.SET_NULL, null=True, related_name="+"
|
||||
)
|
||||
|
||||
class Meta:
|
||||
constraints = [
|
||||
models.UniqueConstraint(
|
||||
fields=("game", "player", "order"), name="unique_answer"
|
||||
),
|
||||
models.UniqueConstraint(fields=("game", "player"), name="unique_answer"),
|
||||
]
|
||||
ordering = ["order"]
|
||||
ordering = ["game"]
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<i class="ri-vip-crown-fill"></i>
|
||||
</th>
|
||||
<th>
|
||||
<i class="ri-mv-line"></i>
|
||||
<i class="ri-mv-fill"></i>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
|
26
game/templates/game/musikgame_answer.html
Normal file
26
game/templates/game/musikgame_answer.html
Normal file
|
@ -0,0 +1,26 @@
|
|||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<h2>Mes réponses</h2>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<i class="ri-mv-fill" alt="Musique"></i>
|
||||
</th>
|
||||
<th>Réponse</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for field in form %}
|
||||
<tr>
|
||||
<td>{{ field.label }}</td>
|
||||
<td>{{ field }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<button type="submit">Valider mes réponses</button>
|
||||
</form>
|
||||
{% endblock content %}
|
|
@ -10,6 +10,9 @@
|
|||
href="{% yt_playlist musikgame %}"
|
||||
role="button"
|
||||
{% if musikgame.playlist_loading %}aria-busy="true"{% endif %}><i class="ri-youtube-fill"></i> Playlist</a>
|
||||
<a target="_blank"
|
||||
href="{% url "game_answer" musikgame.pk %}"
|
||||
role="button"><i class="ri-play-list-2-fill"></i> Répondre</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
<h2>
|
||||
|
|
|
@ -63,4 +63,9 @@ urlpatterns = [
|
|||
views.GroupClearBlacklistView.as_view(),
|
||||
name="group_clear_blacklist",
|
||||
),
|
||||
path(
|
||||
"group/game/<int:pk>/answer/",
|
||||
views.GameAnswerView.as_view(),
|
||||
name="game_answer",
|
||||
),
|
||||
]
|
||||
|
|
|
@ -421,3 +421,34 @@ class GroupClearBlacklistView(MemberFilterMixin, SingleObjectMixin, View):
|
|||
group.musicvideo_set.filter(blacklisted=True).update(blacklisted=False)
|
||||
messages.add_message(request, messages.SUCCESS, "La blacklist a été effacée.")
|
||||
return redirect(group)
|
||||
|
||||
|
||||
class GameAnswerView(LoginRequiredMixin, DetailView):
|
||||
model = models.MusikGame
|
||||
template_name = "game/musikgame_answer.html"
|
||||
|
||||
def get_queryset(self):
|
||||
return super().get_queryset().filter(players=self.request.user)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
return super().get_context_data(**kwargs) | {
|
||||
"form": forms.AnswerForm(game=self.object, user=self.request.user)
|
||||
}
|
||||
|
||||
def post(self, request, pk):
|
||||
game = self.get_object()
|
||||
for music in game.musicgameorder_set.all():
|
||||
answer = request.POST.get(f"answer-{music.order}")
|
||||
if answer:
|
||||
models.MusicGameAnswer.objects.update_or_create(
|
||||
game=music,
|
||||
player=request.user,
|
||||
defaults={"answer": game.players.get(pk=answer)},
|
||||
)
|
||||
else:
|
||||
models.MusicGameAnswer.objects.update_or_create(
|
||||
game=music,
|
||||
player=request.user,
|
||||
defaults={"answer": None},
|
||||
)
|
||||
return redirect("game_answer", pk)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue