Add delete option for votes, add "not voted" votes for later added dates
This commit is contained in:
parent
8d0f520571
commit
8b8868f180
@ -31,7 +31,8 @@ class VotingUserAdmin(admin.ModelAdmin):
|
||||
|
||||
@admin.register(EventDateVotes)
|
||||
class EventDateVotesAdmin(admin.ModelAdmin):
|
||||
list_display = ("id", "voter", "date")
|
||||
list_display = ("id", "voter", "date", "available")
|
||||
list_editable = ('available',)
|
||||
ordering = ("id",)
|
||||
|
||||
|
||||
|
@ -0,0 +1,19 @@
|
||||
# Generated by Django 4.0.5 on 2022-08-05 21:24
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('homepage', '0017_remove_eventdatevotes_available'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='eventdatevotes',
|
||||
name='available',
|
||||
field=models.BooleanField(default=True),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
@ -45,6 +45,7 @@ class ClubhausEvent(models.Model):
|
||||
class EventDateVotes(models.Model):
|
||||
voter = models.ForeignKey(to="VotingUser", on_delete=models.CASCADE)
|
||||
date = models.ForeignKey(to="EventDate", to_field="date", on_delete=models.CASCADE)
|
||||
available = models.BooleanField()
|
||||
|
||||
class Meta:
|
||||
constraints = [
|
||||
|
@ -28,6 +28,15 @@
|
||||
new Date("{{ next_event.date.isoformat }}"),
|
||||
countdown.DAYS | countdown.HOURS | countdown.MINUTES | countdown.SECONDS);
|
||||
</script>
|
||||
<script>
|
||||
const form = document.getElementById('votingForm');
|
||||
form.onsubmit = (e) => {
|
||||
const deleteBtn = document.getElementById("deleteMeBtn")
|
||||
if (e.submitter === deleteBtn) {
|
||||
document.getElementById("deleteMeInput").value = "1"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
@ -61,7 +70,8 @@
|
||||
<!-- links -->
|
||||
<div class="row justify-content-center my-5">
|
||||
<div class="col-auto display-6 m-2">
|
||||
<a href="https://open.spotify.com/playlist/00FYaeOKftIb4zWDEShmtD?si=78a7ac31b6f84992" target="_blank">
|
||||
<a href="https://open.spotify.com/playlist/00FYaeOKftIb4zWDEShmtD?si=78a7ac31b6f84992"
|
||||
target="_blank">
|
||||
<span class="badge rounded-pill text-bg-dark"><i class="bi-spotify"></i> Playlist</span>
|
||||
</a>
|
||||
</div>
|
||||
@ -103,10 +113,12 @@
|
||||
<tr>
|
||||
<td>{{ voter.0.name }}</td>
|
||||
{% for date in voter.1.items %}
|
||||
{% if date.1 %}
|
||||
{% if date.1 == True %}
|
||||
<td><i class="fs-4 text-success bi-check-circle"></i></td>
|
||||
{% else %}
|
||||
{% elif date.1 == False %}
|
||||
<td><i class="fs-4 text-danger bi-x-circle"></i></td>
|
||||
{% else %}
|
||||
<td><i class="fs-4 text-warning bi-question-circle"></i></td>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tr>
|
||||
@ -167,14 +179,15 @@
|
||||
aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content text-bg-dark">
|
||||
<form method="post" action="{% url 'voting' %}">
|
||||
<div class="modal-header">
|
||||
<form id="votingForm" method="post" action="{% url 'voting' %}">
|
||||
<div class="modal-header border-secondary">
|
||||
<h5 class="modal-title" id="exampleModalLabel">Abstimmung</h5>
|
||||
<button type="button" class="btn-close bg-white" data-bs-dismiss="modal"
|
||||
aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
{% csrf_token %}
|
||||
<input id="deleteMeInput" type="hidden" name="deleteClicked" value="0">
|
||||
{% language 'de' %}
|
||||
{% for dateOption in dates %}
|
||||
<div class="form-check">
|
||||
@ -187,20 +200,26 @@
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endlanguage %}
|
||||
<div class="mb-3">
|
||||
<div class="my-3">
|
||||
<label for="nameInput" class="form-label">Name</label>
|
||||
<input type="text" class="form-control" id="nameInput" name="name" required
|
||||
{% if request.session.name %} value="{{ request.session.name }}" {% endif %}>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="modifyKeyInput" class="form-label">Passwort</label>
|
||||
<div>
|
||||
<label for="modifyKeyInput" class="form-label">Parole</label>
|
||||
<input type="text" class="form-control" id="modifyKeyInput" name="modifyKey"
|
||||
{% if request.session.modifyKey %} value="{{ request.session.modifyKey }}" {% endif %}>
|
||||
<div id="modifyKeyHelp" class="form-text">Damit nur du deine Einträge ändern kannst, solltest du ein Passwort vergeben. Tust du dies nicht, kann jeder deine Einträge ändern und löschen!</div>
|
||||
{% if request.session.modifyKey %}
|
||||
value="{{ request.session.modifyKey }}" {% endif %}>
|
||||
<div id="modifyKeyHelp" class="form-text">Damit nur du deine Einträge ändern kannst,
|
||||
solltest du eine Parole vergeben. Tust du dies nicht, kann jeder deine Einträge ändern
|
||||
und löschen!
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="btn btn-primary">Abstimmen</button>
|
||||
</div>
|
||||
<div class="modal-footer border-secondary">
|
||||
<button id="submitVoteBtn" type="submit" class="btn btn-primary order-1">Abstimmen</button>
|
||||
<button id="deleteMeBtn" type="submit" class="btn btn-danger me-auto order-0">Lösche mich
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -36,13 +36,13 @@ def events(request: HttpRequest) -> django.http.HttpResponse:
|
||||
unique_voters = list(set(map(lambda v: v.voter, votes)))
|
||||
vote_map = {}
|
||||
for voter in unique_voters:
|
||||
vote_map[voter] = {date.date.isoformat(): False for date in dates}
|
||||
vote_map[voter] = {date.date.isoformat(): None for date in dates}
|
||||
|
||||
for vote in votes:
|
||||
voter = vote.voter
|
||||
v_date = vote.date.date.isoformat()
|
||||
if voter in vote_map and v_date in vote_map[voter]:
|
||||
vote_map[voter][v_date] = True
|
||||
vote_map[voter][v_date] = vote.available
|
||||
|
||||
return render(request, 'homepage/events.html', {'next_event': next_event, "dates": dates, 'votes': vote_map})
|
||||
else:
|
||||
@ -56,6 +56,10 @@ def voting(request: HttpRequest) -> django.http.HttpResponse:
|
||||
if request.META.get("X-Forwarded-For"):
|
||||
raise ProxyUsageDetected()
|
||||
|
||||
if request.method != "POST":
|
||||
return HttpResponseRedirect(reverse("events"))
|
||||
|
||||
# Check rate limit
|
||||
ip = request.META.get("REMOTE_ADDR")
|
||||
cache_key = f"voting_block_{ip}"
|
||||
rate_cache: django.core.cache.BaseCache = cache
|
||||
@ -63,23 +67,30 @@ def voting(request: HttpRequest) -> django.http.HttpResponse:
|
||||
rate_cache.add(cache_key, 0, django_settings.IP_RATE_LIMIT_TIME)
|
||||
rate_cache.incr(cache_key)
|
||||
|
||||
if request.method != "POST":
|
||||
return HttpResponseRedirect(reverse("events"))
|
||||
|
||||
if rate_cache.get(cache_key) > django_settings.IP_RATE_LIMIT_COUNT:
|
||||
raise RateLimitHit()
|
||||
|
||||
# check params
|
||||
if not request.POST["name"]:
|
||||
return HttpResponseRedirect(reverse("events"))
|
||||
|
||||
name = request.POST["name"]
|
||||
modify_key = request.POST["modifyKey"] or ""
|
||||
if name := request.POST["name"]:
|
||||
|
||||
request.session["name"] = name
|
||||
request.session["modifyKey"] = modify_key
|
||||
|
||||
# handle delete
|
||||
if request.POST["deleteClicked"] == "1":
|
||||
VotingUser.objects.filter(name=name, modify_key=modify_key).delete()
|
||||
return HttpResponseRedirect(reverse("events"))
|
||||
|
||||
# handle normal voting
|
||||
user, _ = VotingUser.objects.get_or_create(name=name, modify_key=modify_key)
|
||||
event_dates = EventDate.objects.filter(event__active=True).order_by("date")
|
||||
|
||||
for date in event_dates:
|
||||
if date.date.isoformat() in request.POST:
|
||||
EventDateVotes.objects.update_or_create(voter=user, date=date)
|
||||
else:
|
||||
EventDateVotes.objects.filter(voter=user, date=date).delete()
|
||||
available = date.date.isoformat() in request.POST
|
||||
EventDateVotes.objects.update_or_create(voter=user, date=date, defaults={"available": available})
|
||||
|
||||
return HttpResponseRedirect(reverse("events"))
|
||||
|
Loading…
Reference in New Issue
Block a user