experiENS/avisstage/api.py

133 lines
4.3 KiB
Python
Raw Normal View History

2017-04-16 00:03:04 +02:00
# coding: utf-8
from tastypie.resources import ModelResource
2017-04-20 23:04:07 +02:00
from tastypie.authentication import SessionAuthentication
from tastypie import fields, utils
2017-04-16 00:03:04 +02:00
2017-05-02 23:23:26 +02:00
from django.contrib.gis import geos
2017-04-25 22:02:23 +02:00
from django.urls import reverse
2017-05-02 23:23:26 +02:00
from .models import Lieu, Stage, Normalien, StageMatiere
2018-12-30 20:33:44 +01:00
from .utils import approximate_distance
2017-05-02 23:23:26 +02:00
2021-02-07 23:15:47 +01:00
2018-12-29 00:12:36 +01:00
class EnScolariteAuthentication(SessionAuthentication):
def is_authenticated(self, request, **kwargs):
if super().is_authenticated(request, **kwargs):
return request.user.profil.en_scolarite
return False
2021-02-07 23:15:47 +01:00
2017-05-02 23:23:26 +02:00
# API principale pour les lieux
2017-04-16 00:03:04 +02:00
class LieuResource(ModelResource):
2021-02-07 23:15:47 +01:00
# stages = fields.ToManyField("avisstage.api.StageResource",
2018-12-29 00:12:36 +01:00
# "stages", use_in="detail", full=True)
2021-02-07 23:15:47 +01:00
2017-04-16 00:03:04 +02:00
class Meta:
queryset = Lieu.objects.all()
resource_name = "lieu"
2017-04-27 03:06:51 +02:00
fields = ["nom", "ville", "pays", "coord", "type_lieu", "id"]
2021-02-07 23:15:47 +01:00
# login_required
2017-05-02 23:23:26 +02:00
authentication = SessionAuthentication()
# Filtres personnalisés
2017-04-19 01:56:15 +02:00
def build_filters(self, filters=None, **kwargs):
2017-04-16 00:03:04 +02:00
if filters is None:
filters = {}
2017-04-20 23:04:07 +02:00
orm_filters = super(LieuResource, self).build_filters(filters, **kwargs)
2017-04-16 00:03:04 +02:00
2017-05-02 23:23:26 +02:00
# Trouver les lieux à proximités d'un point donné
2017-04-16 00:03:04 +02:00
if "lng" in filters and "lat" in filters:
2021-02-07 23:15:47 +01:00
lat = float(filters["lat"])
lng = float(filters["lng"])
pt = geos.Point((lng, lat), srid=4326)
2017-04-16 00:03:04 +02:00
self.reference_point = pt
2021-02-07 23:15:47 +01:00
orm_filters["coord__distance_lte"] = (pt, 10000)
2017-04-16 00:03:04 +02:00
2017-05-02 23:23:26 +02:00
# Filtrer les lieux qui ont déjà des stages
if "has_stage" in filters:
2021-02-07 23:15:47 +01:00
orm_filters["stages__public"] = True
2017-04-16 00:03:04 +02:00
return orm_filters
2017-05-02 23:23:26 +02:00
2017-05-19 22:40:26 +02:00
# Custom apply filters pour ajouter le "distinct"
def apply_filters(self, request, applicable_filters):
return self.get_object_list(request).filter(**applicable_filters).distinct()
2021-02-07 23:15:47 +01:00
2017-05-02 23:23:26 +02:00
# Ajout d'informations
2017-04-16 00:03:04 +02:00
def dehydrate(self, bundle):
bundle = super(LieuResource, self).dehydrate(bundle)
2021-02-07 23:15:47 +01:00
2017-04-16 00:03:04 +02:00
obj = bundle.obj
2021-02-07 23:15:47 +01:00
bundle.data["coord"] = {"lat": float(obj.coord.y), "lng": float(obj.coord.x)}
2017-05-02 23:23:26 +02:00
2018-12-30 20:33:44 +01:00
# Distance au point recherché
if "lat" in bundle.request.GET and "lng" in bundle.request.GET:
2021-02-07 23:15:47 +01:00
bundle.data["distance"] = approximate_distance(
self.reference_point, bundle.obj.coord
)
2017-05-02 23:23:26 +02:00
# Autres infos utiles
bundle.data["pays_nom"] = obj.get_pays_display()
2017-05-02 23:23:26 +02:00
bundle.data["type_lieu_nom"] = obj.type_lieu_fancy
# TODO use annotate?
2021-02-07 23:15:47 +01:00
bundle.data["num_stages"] = obj.stages.filter(public=True).count()
2017-04-20 23:04:07 +02:00
return bundle
2017-05-02 23:23:26 +02:00
2021-02-07 23:15:47 +01:00
2017-05-02 23:23:26 +02:00
# API sur un stage
2017-04-20 23:04:07 +02:00
class StageResource(ModelResource):
class Meta:
queryset = Stage.objects.filter(public=True)
resource_name = "stage"
fields = ["sujet", "date_debut", "date_fin", "matieres", "id"]
2021-02-07 23:15:47 +01:00
# login_required
2018-12-29 00:12:36 +01:00
authentication = EnScolariteAuthentication()
2017-04-20 23:04:07 +02:00
2017-05-02 23:23:26 +02:00
# Filtres personnalisés
2017-04-20 23:04:07 +02:00
def build_filters(self, filters=None, **kwargs):
if filters is None:
filters = {}
orm_filters = super(StageResource, self).build_filters(filters, **kwargs)
2017-05-02 23:23:26 +02:00
# Récupération des stages à un lieu donné
2017-04-20 23:04:07 +02:00
if "lieux" in filters:
2021-02-07 23:15:47 +01:00
flieux = map(int, filters["lieux"].split(","))
orm_filters["lieux__id__in"] = flieux
2017-04-20 23:04:07 +02:00
return orm_filters
2017-05-02 23:23:26 +02:00
# Informations à ajouter
2017-04-20 23:04:07 +02:00
def dehydrate(self, bundle):
bundle = super(StageResource, self).dehydrate(bundle)
obj = bundle.obj
2017-05-02 23:23:26 +02:00
# Affichage des manytomany en condensé
2021-02-07 23:15:47 +01:00
bundle.data["auteur"] = obj.auteur.nom
bundle.data["thematiques"] = list(
obj.thematiques.all().values_list("name", flat=True)
)
bundle.data["matieres"] = list(obj.matieres.all().values_list("nom", flat=True))
2017-05-02 23:23:26 +02:00
# Adresse de la fiche de stage
2021-02-07 23:15:47 +01:00
bundle.data["url"] = reverse("avisstage:stage", kwargs={"pk": obj.id})
2017-04-16 00:03:04 +02:00
return bundle
2017-04-20 23:04:07 +02:00
2021-02-07 23:15:47 +01:00
2017-05-02 23:23:26 +02:00
# Auteurs des fiches (TODO supprimer ?)
2017-04-20 23:04:07 +02:00
class AuteurResource(ModelResource):
2021-02-07 23:15:47 +01:00
stages = fields.ToManyField(
"avisstage.api.StageResource", "stages", use_in="detail"
)
2017-04-20 23:04:07 +02:00
class Meta:
queryset = Normalien.objects.all()
resource_name = "profil"
fields = ["id", "nom", "stages"]
2017-05-02 23:23:26 +02:00
2021-02-07 23:15:47 +01:00
# login_required
2018-12-29 00:12:36 +01:00
authentication = EnScolariteAuthentication()