148 lines
4.9 KiB
Python
148 lines
4.9 KiB
Python
# coding: utf-8
|
|
|
|
from django.shortcuts import render, redirect, get_object_or_404
|
|
from django.contrib.auth.decorators import login_required
|
|
|
|
from django import forms
|
|
from django.db.models import Q
|
|
|
|
from .documents import StageDocument
|
|
from .models import Stage
|
|
from .statics import TYPE_LIEU_OPTIONS, TYPE_STAGE_OPTIONS, NIVEAU_SCOL_OPTIONS
|
|
|
|
from datetime import date
|
|
|
|
# Recherche
|
|
class SearchForm(forms.Form):
|
|
generique = forms.CharField(required=False)
|
|
sujet = forms.CharField(label=u'À propos de', required=False)
|
|
contexte = forms.CharField(label=u'Contexte (lieu, encadrant⋅e⋅s, structure)',
|
|
required=False)
|
|
|
|
apres_annee = forms.IntegerField(label=u'Après cette année', required=False)
|
|
avant_annee = forms.IntegerField(label=u'Avant cette année', required=False)
|
|
|
|
type_stage = forms.ChoiceField(label="Type de stage", choices=([('', u'')]
|
|
+ list(TYPE_STAGE_OPTIONS)),
|
|
required=False)
|
|
niveau_scol = forms.ChoiceField(label="Année d'étude", choices=([('', u'')]
|
|
+ list(NIVEAU_SCOL_OPTIONS)),
|
|
required=False)
|
|
|
|
type_lieu = forms.ChoiceField(label=u"Type de lieu d'accueil",
|
|
choices=([('', u'')]
|
|
+ list(TYPE_LIEU_OPTIONS)),
|
|
required=False)
|
|
tri = forms.ChoiceField(label=u'Tri par',
|
|
choices=[('pertinence', u'Pertinence'),
|
|
('-date_maj',u'Dernière mise à jour')],
|
|
required=False, initial='pertinence')
|
|
|
|
|
|
def cherche(**kwargs):
|
|
filtres = Q(public=True)
|
|
dsl = StageDocument.search()
|
|
|
|
use_dsl = False
|
|
|
|
def field_relevant(field, test_string=True):
|
|
return field in kwargs and \
|
|
kwargs[field] is not None and \
|
|
((not test_string) or kwargs[field].strip() != '')
|
|
|
|
#
|
|
# Recherche libre
|
|
#
|
|
|
|
# Champ générique : recherche dans tous les champs
|
|
if field_relevant("generique"):
|
|
#print "Filtre generique", kwargs['generique']
|
|
dsl = dsl.filter(
|
|
"match",
|
|
_all={"query": kwargs["generique"],
|
|
"fuzziness": "auto"})
|
|
use_dsl = True
|
|
|
|
# Sujet -> Recherche dan les noms de sujets et les thématiques
|
|
if field_relevant("sujet"):
|
|
dsl = dsl.filter("multi_match",
|
|
query = kwargs["sujet"],
|
|
fields = ['sujet^2', 'thematiques'],
|
|
fuzziness = "auto")
|
|
use_dsl = True
|
|
|
|
# Contexte -> Encadrants, structure, lieu
|
|
if field_relevant("contexte"):
|
|
dsl = dsl.filter("multi_match",
|
|
query = kwargs["contexte"],
|
|
fields = ['encadrants', 'structure^2',
|
|
'lieux.nom', 'lieux.pays', 'lieux.ville'],
|
|
fuzziness = "auto")
|
|
use_dsl = True
|
|
|
|
#
|
|
# Filtres directs db
|
|
#
|
|
|
|
# Dates
|
|
if field_relevant('avant_annee', False):
|
|
dte = date(kwargs['avant_annee']+1, 1, 1)
|
|
filtres &= Q(date_fin__lt=dte)
|
|
|
|
if field_relevant('apres_annee', False):
|
|
dte = date(kwargs['apres_annee'], 1, 1)
|
|
filtres &= Q(date_debut__gte=dte)
|
|
|
|
# Type de stage
|
|
if field_relevant('type_stage'):
|
|
filtres &= Q(type_stage=kwargs["type_stage"])
|
|
|
|
if field_relevant('niveau_scol'):
|
|
filtres &= Q(niveau_scol=kwargs["niveau_scol"])
|
|
|
|
# Type de lieu
|
|
if field_relevant('type_lieu'):
|
|
filtres &= Q(lieux__type_lieu=kwargs["type_lieu"])
|
|
|
|
|
|
# Application
|
|
if use_dsl:
|
|
filtres &= Q(id__in=[s.meta.id for s in dsl])
|
|
|
|
#print filtres
|
|
resultat = Stage.objects.filter(filtres)
|
|
tri = 'pertinence'
|
|
|
|
if not use_dsl:
|
|
kwargs['tri'] = '-date_maj'
|
|
|
|
if field_relevant('tri') and kwargs['tri'] != 'pertinence':
|
|
tri = kwargs['tri']
|
|
resultat = resultat.order_by(kwargs['tri'])
|
|
|
|
return resultat, tri
|
|
|
|
@login_required
|
|
def recherche(request):
|
|
form = SearchForm()
|
|
return render(request, 'avisstage/recherche/recherche.html',
|
|
{"form": form})
|
|
|
|
@login_required
|
|
def recherche_resultats(request):
|
|
stages = []
|
|
tri = ''
|
|
vue = 'vue-liste'
|
|
lieux = []
|
|
if request.method == "GET":
|
|
form = SearchForm(request.GET)
|
|
if form.is_valid():
|
|
stages, tri = cherche(**form.cleaned_data)
|
|
lieux = [[stageid, lieuid] for (stageid, lieuid) in stages.values_list('id', 'lieux') if lieuid is not None]
|
|
else:
|
|
form = SearchForm()
|
|
if stages:
|
|
vue = 'vue-hybride'
|
|
return render(request, 'avisstage/recherche/resultats.html',
|
|
{"form": form, "stages":stages,
|
|
"tri": tri, "vue": vue, "lieux": lieux})
|