experiENS/avisstage/views_search.py

148 lines
4.8 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('annee_scol'):
filtres &= Q(annee_scol=kwargs["annee_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 = map(list, stages.values_list('id', 'lieux'))
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})