Application de gestion de courses avec génération de dossards avec QRcode et scan des coureurs à l'arrivée.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

71 lines
2.3 KiB

from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from courses.models import Course, Arrivee
from coureurs.models import Coureur
from django.utils import timezone
from courses.templatetags.temps_format import seconds_to_hms
from .forms import ScanForm
@login_required
def scan_view(request):
from django.shortcuts import get_object_or_404
courses = Course.objects.filter(depart__isnull=False, fin__isnull=True)
result = None
error = None
course = None
# Traitement AJAX POST
if request.method == 'POST' and request.headers.get('x-requested-with') == 'XMLHttpRequest':
course_id = request.POST.get('course_id')
qrcode = request.POST.get('qrcode')
if not course_id or not qrcode:
error = "Paramètres manquants."
elif qrcode.count(';') != 1:
error = "Format QR code invalide."
else:
nom, classe = qrcode.split(';')
course = get_object_or_404(Course, id=course_id)
if not course.depart:
error = "La course n'a pas démarré."
else:
coureur, _ = Coureur.objects.get_or_create(nom=nom.strip(), classe=classe.strip())
if Arrivee.objects.filter(course=course, coureur=coureur).exists():
error = "Ce coureur a déjà été scanné."
else:
temps = timezone.now() - course.depart
rang = Arrivee.objects.filter(course=course).count() + 1
Arrivee.objects.create(course=course, coureur=coureur, temps=temps, rang=rang)
result = {
'nom': coureur.nom,
'classe': coureur.classe,
'rang': rang,
'temps': str(seconds_to_hms(temps))
}
# Broadcast websocket
channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(
f'course_{course.id}',
{
'type': 'send_arrivee',
'data': result
}
)
# Retourne juste le fragment HTML pour scanResult
if result:
return render(request, 'scan_result.html', {'result': result})
else:
return render(request, 'scan_result.html', {'error': error})
# Affichage classique GET
else:
course_id = request.GET.get('course_id')
if course_id:
course = get_object_or_404(Course, id=course_id)
return render(request, 'scan.html', {
'courses': courses,
'result': result,
'error': error,
'course': course
})