Merge branch 'no-es-required' into 'master'

Développer sans ElasticSearch

See merge request klub-dev-ens/experiENS!6
This commit is contained in:
Robin Champenois 2019-01-14 22:40:10 +01:00
commit 092c373f2a
4 changed files with 75 additions and 37 deletions

View file

@ -41,9 +41,13 @@ Vous pouvez alors lancez le serveur de développement
python manage.py runserver python manage.py runserver
C'est bon, vous pouvez développer sur ExpériENS !
## Configuration de la recherche ## Configuration de la recherche
Il faut installer elasticsearch 5.*. C'est compliqué. Mais en suivant https://www.elastic.co/guide/en/elasticsearch/reference/5.4/deb.html ça va. **Cette partie n'est pas obligatoire pour faire fonctionner un serveur de développement en local.** Elle n'est utile que si vous voulez toucher aux fonctionnalités de recherche.
Il faut installer elasticsearch 5.*. C'est compliqué. Mais en suivant https://www.elastic.co/guide/en/elasticsearch/reference/5.4/deb.html c'est faisable.
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add - wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
sudo apt-get install apt-transport-https sudo apt-get install apt-transport-https
@ -54,11 +58,13 @@ Il faut installer elasticsearch 5.*. C'est compliqué. Mais en suivant https://w
sudo systemctl enable elasticsearch.service sudo systemctl enable elasticsearch.service
sudo systemctl start elasticsearch.service sudo systemctl start elasticsearch.service
Et puis, de retour dans le virtualenv python Vous devez ensuite activer ElasticSearch dans vos paramètres locaux, en changeant `USE_ELASTICSEARCH = True` à la fin du fichier `experiENS/settings_dev.py`.
Enfin, de retour dans la console et le virtualenv python, vous pouvez faire
python manage.py search_index --rebuild python manage.py search_index --rebuild
Si des erreurs s'affichent, il y a une cachuète dans le beurre. Si des erreurs s'affichent, demandez de l'aide sur Merle ou par e-mail.
## Changer le CSS ## Changer le CSS

View file

@ -4,6 +4,7 @@ from datetime import date
from django import forms from django import forms
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.conf import settings
from django.core.cache import cache from django.core.cache import cache
from django.core.paginator import Paginator from django.core.paginator import Paginator
from django.db.models import Q, Case, When from django.db.models import Q, Case, When
@ -13,7 +14,11 @@ from django.shortcuts import render, redirect, get_object_or_404
import json import json
import logging import logging
from .documents import StageDocument USE_ELASTICSEARCH = getattr(settings, "USE_ELASTICSEARCH", True)
if USE_ELASTICSEARCH:
from .documents import StageDocument
from .decorators import en_scolarite_required from .decorators import en_scolarite_required
from .models import Stage from .models import Stage
from .statics import TYPE_LIEU_OPTIONS, TYPE_STAGE_OPTIONS, NIVEAU_SCOL_OPTIONS from .statics import TYPE_LIEU_OPTIONS, TYPE_STAGE_OPTIONS, NIVEAU_SCOL_OPTIONS
@ -50,8 +55,6 @@ class SearchForm(forms.Form):
def cherche(**kwargs): def cherche(**kwargs):
filtres = Q(public=True) filtres = Q(public=True)
dsl = StageDocument.search()
use_dsl = False use_dsl = False
def field_relevant(field, test_string=True): def field_relevant(field, test_string=True):
@ -59,35 +62,53 @@ def cherche(**kwargs):
kwargs[field] is not None and \ kwargs[field] is not None and \
((not test_string) or kwargs[field].strip() != '') ((not test_string) or kwargs[field].strip() != '')
# if USE_ELASTICSEARCH:
# Recherche libre dsl = StageDocument.search()
#
# Champ générique : recherche dans tous les champs
if field_relevant("generique"):
#print("Filtre generique", kwargs['generique'])
dsl = dsl.query(
"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"): # Recherche libre AVEC ELASTICSEARCH
dsl = dsl.query("multi_match", #
query = kwargs["sujet"],
fields = ['sujet^2', 'thematiques', 'matieres'],
fuzziness = "auto")
use_dsl = True
# Contexte -> Encadrants, structure, lieu # Champ générique : recherche dans tous les champs
if field_relevant("contexte"): if field_relevant("generique"):
dsl = dsl.query("multi_match", #print("Filtre generique", kwargs['generique'])
query = kwargs["contexte"], dsl = dsl.query(
fields = ['encadrants', 'structure^2', "match",
'lieux.nom', 'lieux.pays', 'lieux.ville'], _all={"query": kwargs["generique"],
fuzziness = "auto") "fuzziness": "auto"})
use_dsl = True use_dsl = True
# Sujet -> Recherche dan les noms de sujets et les thématiques
if field_relevant("sujet"):
dsl = dsl.query("multi_match",
query = kwargs["sujet"],
fields = ['sujet^2', 'thematiques', 'matieres'],
fuzziness = "auto")
use_dsl = True
# Contexte -> Encadrants, structure, lieu
if field_relevant("contexte"):
dsl = dsl.query("multi_match",
query = kwargs["contexte"],
fields = ['encadrants', 'structure^2',
'lieux.nom', 'lieux.pays', 'lieux.ville'],
fuzziness = "auto")
use_dsl = True
else:
# Sans ElasticSearch, on active quand même une approximation de
# recherche en base de données
if field_relevant("generique"):
generique = kwargs["generique"]
filtres = (Q(sujet__icontains=generique)
| Q(thematiques__name__icontains=generique)
| Q(matieres__nom__icontains=generique)
| Q(lieux__nom__icontains=generique))
# Autres champs -> non fonctionnels
if field_relevant("sujet") or field_relevant("contexte"):
raise NotImplementedError(
"ElasticSearch doit être activé pour ce type de recherche")
# #
# Filtres directs db # Filtres directs db
@ -115,7 +136,7 @@ def cherche(**kwargs):
# Application # Application
if use_dsl: if USE_ELASTICSEARCH and use_dsl:
filtres &= Q(id__in=[s.meta.id for s in dsl.scan()]) filtres &= Q(id__in=[s.meta.id for s in dsl.scan()])
#print(filtres) #print(filtres)

View file

@ -21,7 +21,7 @@ ALLOWED_HOSTS = []
# Application definition # Application definition
INSTALLED_APPS = ( INSTALLED_APPS = [
'django.contrib.admin', 'django.contrib.admin',
'django.contrib.auth', 'django.contrib.auth',
'django.contrib.contenttypes', 'django.contrib.contenttypes',
@ -49,7 +49,7 @@ INSTALLED_APPS = (
'taggit', 'taggit',
'taggit_autosuggest', 'taggit_autosuggest',
'avisstage' 'avisstage'
) ]
MIDDLEWARE_CLASSES = ( MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
@ -61,6 +61,7 @@ MIDDLEWARE_CLASSES = (
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
) )
TEMPLATES = [ TEMPLATES = [
{ {
'BACKEND': 'django.template.backends.django.DjangoTemplates', 'BACKEND': 'django.template.backends.django.DjangoTemplates',
@ -83,6 +84,7 @@ TEMPLATES = [
}, },
] ]
ROOT_URLCONF = 'experiENS.urls' ROOT_URLCONF = 'experiENS.urls'
WSGI_APPLICATION = 'experiENS.wsgi.application' WSGI_APPLICATION = 'experiENS.wsgi.application'
@ -94,7 +96,7 @@ WSGI_APPLICATION = 'experiENS.wsgi.application'
# Internationalization # Internationalization
# https://docs.djangoproject.com/en/1.7/topics/i18n/ # https://docs.djangoproject.com/en/1.7/topics/i18n/
LANGUAGE_CODE = 'fr-fr' LANGUAGE_CODE = 'fr'
TIME_ZONE = 'Europe/Paris' TIME_ZONE = 'Europe/Paris'

View file

@ -11,6 +11,7 @@ DATABASES = {
} }
} }
"""
INSTALLED_APPS += ( INSTALLED_APPS += (
'debug_toolbar', 'debug_toolbar',
) )
@ -18,6 +19,7 @@ INSTALLED_APPS += (
MIDDLEWARE_CLASSES = ( MIDDLEWARE_CLASSES = (
'debug_toolbar.middleware.DebugToolbarMiddleware', 'debug_toolbar.middleware.DebugToolbarMiddleware',
) + MIDDLEWARE_CLASSES ) + MIDDLEWARE_CLASSES
"""
INTERNAL_IPS = ['127.0.0.1'] INTERNAL_IPS = ['127.0.0.1']
@ -37,3 +39,10 @@ ELASTICSEARCH_DSL = {
CLIPPER_LDAP_SERVER = 'ldaps://localhost:636' CLIPPER_LDAP_SERVER = 'ldaps://localhost:636'
# Changer à True pour développer avec ES
USE_ELASTICSEARCH = False
if not USE_ELASTICSEARCH:
INSTALLED_APPS.remove('django_elasticsearch_dsl')