Implement rating

main
Luca 2 years ago
parent f299811620
commit 74cdcd9077

@ -147,3 +147,16 @@ SHEET_TO_MODEL = {
} }
YOUTUBE_RE = r'(?:|(?:|(?:http(?:|s):))//)(?:youtu\.be/|(?:|(?:m|www)\.)youtube\.com/watch\?v=)([-0-9A-Z_a-z]{11})' YOUTUBE_RE = r'(?:|(?:|(?:http(?:|s):))//)(?:youtu\.be/|(?:|(?:m|www)\.)youtube\.com/watch\?v=)([-0-9A-Z_a-z]{11})'
RATING_CHOICES = (
('10', 'sehr gut'),
( '9', 'ziemlich gut'),
( '8', 'gut'),
( '7', 'eher gut'),
( '6', 'ok'),
( '5', 'naja'),
( '4', 'eher schlecht'),
( '3', 'schlecht'),
( '2', 'ziemlich schlecht'),
( '1', 'sehr schlecht'),
)

@ -1,2 +1,5 @@
from django import forms from django import forms
from django.conf import settings
class RateArtistForm(forms.Form):
rating = forms.ChoiceField(choices=settings.RATING_CHOICES, required=False, widget=forms.RadioSelect)

@ -0,0 +1,89 @@
# Generated by Django 4.1.4 on 2022-12-20 21:28
from django.db import migrations, models
import django.db.models.deletion
import musicrate.vote.models
class Migration(migrations.Migration):
initial = True
dependencies = [
("core", "0004_alter_artist_link_1_alter_artist_link_2"),
]
operations = [
migrations.CreateModel(
name="Participant",
fields=[
(
"token",
models.CharField(
default=musicrate.vote.models.participant_token,
max_length=43,
primary_key=True,
serialize=False,
),
),
(
"session",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="core.session"
),
),
],
),
migrations.CreateModel(
name="Rating",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"value",
models.CharField(
blank=True,
choices=[
("1", "sehr schlecht"),
("2", "ziemlich schlecht"),
("3", "schlecht"),
("4", "eher schlecht"),
("5", "naja"),
("6", "ok"),
("7", "eher gut"),
("8", "gut"),
("9", "ziemlich gut"),
("10", "sehr gut"),
],
max_length=2,
),
),
(
"artist",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="core.artist"
),
),
(
"participant",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="vote.participant",
),
),
],
),
migrations.AddConstraint(
model_name="rating",
constraint=models.UniqueConstraint(
fields=("artist", "participant"), name="unique_rating"
),
),
]

@ -1,3 +1,24 @@
from django.conf import settings
from django.db import models from django.db import models
from secrets import token_urlsafe
from ..core.models import Artist, Session
# Create your models here. # Create your models here.
def participant_token():
return token_urlsafe(32)
class Participant(models.Model):
token = models.CharField(max_length=43, default=participant_token, primary_key=True)
session = models.ForeignKey(Session, on_delete=models.CASCADE)
class Rating(models.Model):
class Meta:
constraints = [
models.UniqueConstraint(fields=['artist', 'participant'], name='unique_rating'),
]
value = models.CharField(max_length=2, blank=True, choices=settings.RATING_CHOICES)
artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
participant = models.ForeignKey(Participant, on_delete=models.CASCADE)

@ -7,28 +7,14 @@
<p>{{ artist.genre }} &middot; {{ artist.origin }}<br>{{ artist.comment }}</p> <p>{{ artist.genre }} &middot; {{ artist.origin }}<br>{{ artist.comment }}</p>
<form action="" method="post"> <form action="" method="post">
{% csrf_token %}
<div class="rating-container"> <div class="rating-container">
<div class="rating" style="--num-choices: 10"> <div class="rating" style="--num-choices: {{ form.rating | length }}">
<input id="rating10" name="rating" type="radio" value="10"> {% for radio in form.rating %}
<label class="rating-point" for="rating10"></label> {{ radio.tag }}
<input id="rating09" name="rating" type="radio" value="9"> <label class="rating-point" for="{{ radio.id_for_label }}"></label>
<label class="rating-point" for="rating09"></label> {% endfor %}
<input id="rating08" name="rating" type="radio" value="8">
<label class="rating-point" for="rating08"></label>
<input id="rating07" name="rating" type="radio" value="7">
<label class="rating-point" for="rating07"></label>
<input id="rating06" name="rating" type="radio" value="6">
<label class="rating-point" for="rating06"></label>
<input id="rating05" name="rating" type="radio" value="5">
<label class="rating-point" for="rating05"></label>
<input id="rating04" name="rating" type="radio" value="4">
<label class="rating-point" for="rating04"></label>
<input id="rating03" name="rating" type="radio" value="3">
<label class="rating-point" for="rating03"></label>
<input id="rating02" name="rating" type="radio" value="2">
<label class="rating-point" for="rating02"></label>
<input id="rating01" name="rating" type="radio" value="1">
<label class="rating-point" for="rating01"></label>
</div> </div>
<div class="legend"> <div class="legend">
<span>sehr schlecht</span> <span>sehr schlecht</span>
@ -36,22 +22,53 @@
<span>sehr gut</span> <span>sehr gut</span>
</div> </div>
<div class="buttons"> <div class="buttons">
<button type="reset">Zurücksetzen</button> <button id="reset_rating" type="reset">Zurücksetzen</button>
<button id="submit_rating" type="submit">Speichern</button>
</div> </div>
</div> </div>
</form> </form>
<div class="pagination"> <div class="pagination">
{% if offset > 0 %} {% if offset > 0 %}
<a href="{% url 'artist' playlist offset|add:-1 %}">&lt; Zurück</a> <a href="{% url 'artist' playlist.pk offset|add:-1 %}">&lt; Zurück</a>
{% else %} {% else %}
<a></a> <a></a>
{% endif %} {% endif %}
{{ offset|add:1 }}/{{ count }} {{ offset|add:1 }}/{{ count }}
{% if offset < count|add:-1 %} {% if offset < count|add:-1 and has_rating %}
<a href="{% url 'artist' playlist offset|add:1 %}">Weiter &gt;</a> <a href="{% url 'artist' playlist.pk offset|add:1 %}">Weiter &gt;</a>
{% else %} {% else %}
<a></a> <a></a>
{% endif %} {% endif %}
</div> </div>
<script>
const options = document.querySelectorAll('input[name=rating]');
const submitRating = document.getElementById('submit_rating');
let empty = true;
options.forEach(option => {
empty &&= !option.checked;
});
if (empty) {
submitRating.innerText = 'Enthalten';
options.forEach(option => {
option.addEventListener('change', () => {
submitRating.innerText = 'Speichern';
});
});
}
document.getElementById('reset_rating').addEventListener('click', () => {
options.forEach(option => {
if (option.attributes.getNamedItem('checked') !== null) {
option.attributes.removeNamedItem('checked');
}
});
submitRating.innerText = 'Enthalten';
});
</script>
{% endblock %} {% endblock %}

@ -1,5 +1,7 @@
from django.shortcuts import get_object_or_404, redirect, render from django.shortcuts import get_object_or_404, redirect, render
from .forms import RateArtistForm
from .models import Participant, Rating
from ..core.models import Session from ..core.models import Session
# Create your views here. # Create your views here.
@ -7,20 +9,53 @@ from ..core.models import Session
def join_session(request, session): def join_session(request, session):
session = get_object_or_404(Session, pk=session) session = get_object_or_404(Session, pk=session)
if 'token' in request.session:
try:
participant = Participant.objects.get(pk=request.session['token'])
return redirect('current_artist', session.pk)
except Participant.DoesNotExist:
del request.session['token']
if request.method == 'POST': if request.method == 'POST':
request.session['session'] = session.token participant = Participant(session=session)
participant.save()
request.session['token'] = participant.pk
return redirect('current_artist', session.playlist.pk) return redirect('current_artist', session.playlist.pk)
return render(request, 'vote/join_session.html', {}) return render(request, 'vote/join_session.html', {})
def artist(request, playlist, offset=None): def artist(request, playlist, offset=None):
session = get_object_or_404(Session, pk=request.session.get('session')) participant = get_object_or_404(Participant, pk=request.session.get('token'))
session_offset = participant.session.offset
offset = offset if offset != None else session_offset
if offset > session_offset:
return redirect('artist', playlist, session_offset)
offset = offset if offset != None else session.offset playlist = participant.session.playlist
if offset > session.offset:
return redirect('artist', playlist, session.offset)
artists = session.playlist.artist_set artists = playlist.artist_set
artist = artists.order_by('id')[offset] artist = artists.order_by('id')[offset]
return render(request, 'vote/artist.html', {'artist': artist, 'count': artists.count(), 'offset': offset, 'playlist': session.playlist.pk}) rating = None
if Rating.objects.filter(artist=artist, participant=participant).exists():
rating = Rating.objects.get(artist=artist, participant=participant)
form = RateArtistForm()
if request.method == 'POST':
form = RateArtistForm(request.POST)
if not form.is_valid():
return redirect('artist', playlist, session_offset)
if not rating:
rating = Rating(artist=artist, participant=participant)
rating.value = form.cleaned_data['rating']
rating.save()
elif rating and rating.value:
form = RateArtistForm({'rating': rating.value})
has_rating = rating != None
return render(request, 'vote/artist.html', {'artist': artist, 'count': artists.count(), 'form': form, 'has_rating': has_rating, 'offset': offset, 'playlist': playlist})

Loading…
Cancel
Save