Rewrite bda.views.catalogue

- No string concatenations
- Use `get_object_or_404` instead of performing a `.get` and catching
  the eventual exception.
- More accurate error messages when a bad request is detected.
- More accurate error handling
This commit is contained in:
Martin Pépin 2017-04-05 19:33:18 +01:00
parent a262983170
commit 853a239e6e

View file

@ -22,7 +22,6 @@ from django.core.urlresolvers import reverse
from django.conf import settings from django.conf import settings
from django.utils import timezone, formats from django.utils import timezone, formats
from django.views.generic.list import ListView from django.views.generic.list import ListView
from django.core.exceptions import ObjectDoesNotExist
from gestioncof.decorators import cof_required, buro_required from gestioncof.decorators import cof_required, buro_required
from bda.models import ( from bda.models import (
Spectacle, Participant, ChoixSpectacle, Attribution, Tirage, Spectacle, Participant, ChoixSpectacle, Attribution, Tirage,
@ -657,29 +656,34 @@ def catalogue(request, request_type):
if request_type == "list": if request_type == "list":
# Dans ce cas on retourne la liste des tirages et de leur id en JSON # Dans ce cas on retourne la liste des tirages et de leur id en JSON
data_return = list( data_return = list(
Tirage.objects.filter(appear_catalogue=True).values('id', 'title')) Tirage.objects.filter(appear_catalogue=True).values('id', 'title')
)
return JsonResponse(data_return, safe=False) return JsonResponse(data_return, safe=False)
if request_type == "details": if request_type == "details":
# Dans ce cas on retourne une liste des catégories et des salles # Dans ce cas on retourne une liste des catégories et des salles
tirage_id = request.GET.get('id', '') tirage_id = request.GET.get('id', None)
try: if tirage_id is None:
tirage = Tirage.objects.get(id=tirage_id)
except ObjectDoesNotExist:
return HttpResponseBadRequest( return HttpResponseBadRequest(
"Aucun tirage correspondant à l'id " "Missing GET parameter: id <int>"
+ tirage_id) )
try:
tirage = get_object_or_404(Tirage, id=int(tirage_id))
except ValueError: except ValueError:
return HttpResponseBadRequest( return HttpResponseBadRequest(
"Mauvais format d'identifiant : " "Bad format: int expected for `id`"
+ tirage_id) )
categories = list( categories = list(
CategorieSpectacle.objects.filter( CategorieSpectacle.objects
spectacle__in=tirage.spectacle_set.all()) .filter(spectacle__in=tirage.spectacle_set.all())
.distinct().values('id', 'name')) .distinct()
.values('id', 'name')
)
locations = list( locations = list(
Salle.objects.filter( Salle.objects
spectacle__in=tirage.spectacle_set.all()) .filter(spectacle__in=tirage.spectacle_set.all())
.distinct().values('id', 'name')) .distinct()
.values('id', 'name')
)
data_return = {'categories': categories, 'locations': locations} data_return = {'categories': categories, 'locations': locations}
return JsonResponse(data_return, safe=False) return JsonResponse(data_return, safe=False)
if request_type == "descriptions": if request_type == "descriptions":
@ -687,34 +691,35 @@ def catalogue(request, request_type):
# à la salle spécifiées # à la salle spécifiées
tirage_id = request.GET.get('id', '') tirage_id = request.GET.get('id', '')
categories = request.GET.get('category', '[0]') categories = request.GET.get('category', '[]')
locations = request.GET.get('location', '[0]') locations = request.GET.get('location', '[]')
try: try:
category_id = json.loads(categories) tirage_id = int(tirage_id)
location_id = json.loads(locations) categories_id = json.loads(categories)
tirage = Tirage.objects.get(id=tirage_id) locations_id = json.loads(locations)
# Integers expected
shows_qs = tirage.spectacle_set if not all(isinstance(id, int) for id in categories_id):
if not(0 in category_id): raise ValueError
shows_qs = shows_qs.filter( if not all(isinstance(id, int) for id in locations_id):
category__id__in=category_id) raise ValueError
if not(0 in location_id):
shows_qs = shows_qs.filter(
location__id__in=location_id)
except ObjectDoesNotExist:
return HttpResponseBadRequest(
"Impossible de trouver des résultats correspondant à ces "
"caractéristiques : id = {}, catégories = {}, salles = {}"
.format(tirage_id, categories, locations)
)
except ValueError: # Contient JSONDecodeError except ValueError: # Contient JSONDecodeError
return HttpResponseBadRequest( return HttpResponseBadRequest(
"Impossible de parser les paramètres donnés : " "Parse error, please ensure the GET parameters have the "
"id = {}, catégories = {}, salles = {}" "following types:\n"
"id: int, category: [int], location: [int]\n"
"Data received:\n"
"id = {}, category = {}, locations = {}"
.format(request.GET.get('id', ''), .format(request.GET.get('id', ''),
request.GET.get('category', '[0]'), request.GET.get('category', '[]'),
request.GET.get('location', '[0]')) request.GET.get('location', '[]'))
) )
tirage = get_object_or_404(Tirage, id=tirage_id)
shows_qs = tirage.spectacle_set
if categories_id:
shows_qs = shows_qs.filter(category__id__in=categories_id)
if locations_id:
shows_qs = shows_qs.filter(location__id__in=locations_id)
# On convertit les descriptions à envoyer en une liste facilement # On convertit les descriptions à envoyer en une liste facilement
# JSONifiable (il devrait y avoir un moyen plus efficace en # JSONifiable (il devrait y avoir un moyen plus efficace en