# coding: utf-8 from tastypie.resources import ModelResource from tastypie.authentication import SessionAuthentication from tastypie import fields, utils from django.contrib.gis import geos from django.urls import reverse from .models import Lieu, Stage, Normalien, StageMatiere # API principale pour les lieux class LieuResource(ModelResource): stages = fields.ToManyField("avisstage.api.StageResource", "stages", use_in="detail", full=True) class Meta: queryset = Lieu.objects.all() resource_name = "lieu" fields = ["nom", "ville", "pays", "coord", "type_lieu", "id"] #login_required authentication = SessionAuthentication() # Filtres personnalisés def build_filters(self, filters=None, **kwargs): if filters is None: filters = {} orm_filters = super(LieuResource, self).build_filters(filters, **kwargs) # Trouver les lieux à proximités d'un point donné if "lng" in filters and "lat" in filters: lat = float(filters['lat']) lng = float(filters['lng']) pt = geos.Point((lng,lat), srid=4326) self.reference_point = pt orm_filters['coord__distance_lte'] = (pt, 50) # Filtrer les lieux qui ont déjà des stages if "has_stage" in filters: orm_filters['stages__public'] = True return orm_filters # Custom apply filters pour ajouter le "distinct" def apply_filters(self, request, applicable_filters): return self.get_object_list(request).filter(**applicable_filters).distinct() # Ajout d'informations def dehydrate(self, bundle): bundle = super(LieuResource, self).dehydrate(bundle) obj = bundle.obj bundle.data['coord'] = {'lat': float(obj.coord.y), 'lng': float(obj.coord.x)} # Distance au point recherché (inutile en fait) #if "lat" in bundle.request.GET and "lng" in bundle.request.GET: # bundle.data['distance'] = self.reference_point.distance(bundle.obj.coord) # Autres infos utiles bundle.data["pays_nom"] = obj.get_pays_display() bundle.data["type_lieu_nom"] = obj.type_lieu_fancy # TODO use annotate? bundle.data["num_stages"] = obj.stages.filter(public=True).count() return bundle # API sur un stage class StageResource(ModelResource): class Meta: queryset = Stage.objects.filter(public=True) resource_name = "stage" fields = ["sujet", "date_debut", "date_fin", "matieres", "id"] #login_required authentication = SessionAuthentication() # Filtres personnalisés def build_filters(self, filters=None, **kwargs): if filters is None: filters = {} orm_filters = super(StageResource, self).build_filters(filters, **kwargs) # Récupération des stages à un lieu donné if "lieux" in filters: flieux = map(int, filters['lieux'].split(',')) orm_filters['lieux__id__in'] = flieux return orm_filters # Informations à ajouter def dehydrate(self, bundle): bundle = super(StageResource, self).dehydrate(bundle) obj = bundle.obj # Affichage des manytomany en condensé 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)) # Adresse de la fiche de stage bundle.data['url'] = reverse("avisstage:stage", kwargs={"pk": obj.id}); return bundle # Auteurs des fiches (TODO supprimer ?) class AuteurResource(ModelResource): stages = fields.ToManyField("avisstage.api.StageResource", "stages", use_in="detail") class Meta: queryset = Normalien.objects.all() resource_name = "profil" fields = ["id", "nom", "stages"] #login_required authentication = SessionAuthentication()