From: Eric Mc Sween Date: Thu, 4 Nov 2010 18:54:23 +0000 (-0400) Subject: Réparé la recherche par mots-clés X-Git-Url: https://git.auf.org/?p=auf_savoirs_en_partage_django.git;a=commitdiff_plain;h=82f25472cbeca5b54950885cf50418a1cf81f082 Réparé la recherche par mots-clés J'ai aussi essayé d'optimiser les requêtes un peu... --- diff --git a/auf_savoirs_en_partage/chercheurs/models.py b/auf_savoirs_en_partage/chercheurs/models.py index 0194404..75a6f82 100644 --- a/auf_savoirs_en_partage/chercheurs/models.py +++ b/auf_savoirs_en_partage/chercheurs/models.py @@ -49,19 +49,24 @@ class ChercheurQuerySet(models.query.QuerySet): def search(self, text): q = None for word in text.split(): + matching_pays = list(Pays.objects.filter(Q(nom__icontains=word) | Q(region__nom__icontains=word)).values_list('pk', flat=True)) + matching_etablissements = list(Etablissement.objects.filter(Q(nom__icontains=word) | Q(pays__in=matching_pays)).values_list('pk', flat=True)) + matching_publications = list(Publication.objects.filter(titre__icontains=word).values_list('pk', flat=True)) + matching_groupes = list(Groupe.objects.filter(nom__icontains=word).values_list('pk', flat=True)) + matching_disciplines = list(Discipline.objects.filter(nom__icontains=word).values_list('pk', flat=True)) part = (Q(personne__nom__icontains=word) | Q(personne__prenom__icontains=word) | Q(theme_recherche__icontains=word) | + Q(etablissement__in=matching_etablissements) | Q(etablissement_autre_nom__icontains=word) | - Q(etablissement__nom__icontains=word) | - Q(etablissement__pays__nom__icontains=word) | - Q(discipline__nom__icontains=word) | - Q(publication1__titre__icontains=word) | - Q(publication2__titre__icontains=word) | - Q(publication3__titre__icontains=word) | - Q(publication4__titre__icontains=word) | - Q(these__titre__icontains=word) | - Q(groupes__nom__icontains=word)) + Q(etablissement_autre_pays__in=matching_pays) | + Q(discipline__in=matching_disciplines) | + Q(publication1__in=matching_publications) | + Q(publication2__in=matching_publications) | + Q(publication3__in=matching_publications) | + Q(publication4__in=matching_publications) | + Q(these__in=matching_publications) | + Q(groupes__in=matching_groupes)) if q is None: q = part else: diff --git a/auf_savoirs_en_partage/development.py b/auf_savoirs_en_partage/development.py index 70d35bf..0f28876 100644 --- a/auf_savoirs_en_partage/development.py +++ b/auf_savoirs_en_partage/development.py @@ -6,6 +6,6 @@ AUTH_PASSWORD_REQUIRED = False # Activer la debug toolbar... -# MIDDLEWARE_CLASSES += ('debug_toolbar.middleware.DebugToolbarMiddleware',) -# INSTALLED_APPS += ('debug_toolbar',) +MIDDLEWARE_CLASSES += ('debug_toolbar.middleware.DebugToolbarMiddleware',) +INSTALLED_APPS += ('debug_toolbar',) # DEBUG_TOOLBAR_CONFIG = dict(INTERCEPT_REDIRECTS=False) diff --git a/auf_savoirs_en_partage/savoirs/lib/recherche.py b/auf_savoirs_en_partage/savoirs/lib/recherche.py index c7ef9dc..65804a8 100644 --- a/auf_savoirs_en_partage/savoirs/lib/recherche.py +++ b/auf_savoirs_en_partage/savoirs/lib/recherche.py @@ -170,18 +170,21 @@ def build_search_regexp(query): part = re.escape(word.lower()) # Les expressions régulières ne connaissent pas la version # en majuscules des caractères accentués. :( - part = part.replace(u'à', u'[àÀ]') - part = part.replace(u'â', u'[âÂ]') - part = part.replace(u'é', u'[éÉ]') - part = part.replace(u'ê', u'[êÊ]') - part = part.replace(u'î', u'[îÎ]') - part = part.replace(u'ç', u'[çÇ]') + # Attention: re.escape aura ajouté un backslash devant tous les + # caractères accentués... + part = part.replace(u'\\à', u'[àÀ]') + part = part.replace(u'\\â', u'[âÂ]') + part = part.replace(u'\\é', u'[éÉ]') + part = part.replace(u'\\ê', u'[êÊ]') + part = part.replace(u'\\î', u'[îÎ]') + part = part.replace(u'\\ô', u'[ôÔ]') + part = part.replace(u'\\ç', u'[çÇ]') # Faire ceci après avoir traité les caractères accentués... part = part.replace('a', u'[aàâÀÂ]') part = part.replace('e', u'[eéèëêÉÊ]') part = part.replace('i', u'[iïîÎ]') - part = part.replace('o', u'[oô]') + part = part.replace('o', u'[oôÔ]') part = part.replace('u', u'[uûüù]') part = part.replace('c', u'[cç]') diff --git a/auf_savoirs_en_partage/savoirs/models.py b/auf_savoirs_en_partage/savoirs/models.py index 31d5732..2ea3256 100644 --- a/auf_savoirs_en_partage/savoirs/models.py +++ b/auf_savoirs_en_partage/savoirs/models.py @@ -41,7 +41,15 @@ class ActualiteManager(models.Manager): class ActualiteQuerySet(models.query.QuerySet): def search(self, text): - return self.filter(Q(titre__icontains=text) | Q(texte__icontains=text)) + q = None + for word in text.split(): + part = (Q(titre__icontains=word) | Q(texte__icontains=word) | + Q(regions__nom__icontains=word) | Q(disciplines__nom__icontains=word)) + if q is None: + q = part + else: + q = q & part + return self.filter(q).distinct() if q is not None else self class Actualite(models.Model): id = models.AutoField(primary_key=True, db_column='id_actualite') @@ -81,7 +89,6 @@ class EvenementManager(models.Manager): class EvenementQuerySet(models.query.QuerySet): def search(self, text): - qs = self q = None for word in text.split(): part = (Q(titre__icontains=word) | @@ -91,12 +98,13 @@ class EvenementQuerySet(models.query.QuerySet): Q(type__icontains=word) | Q(lieu__icontains=word) | Q(description__icontains=word) | - Q(contact__icontains=word)) + Q(contact__icontains=word) | + Q(regions__nom__icontains=word)) if q is None: q = part else: q = q & part - return qs.filter(q) if q is not None else qs + return self.filter(q).distinct() if q is not None else self def search_titre(self, text): qs = self @@ -278,10 +286,11 @@ class RecordQuerySet(models.query.QuerySet): # demandés. q = None for word in words: + matching_pays = list(Pays.objects.filter(Q(nom__icontains=word) | Q(region__nom__icontains=word)).values_list('pk', flat=True)) part = (Q(title__icontains=word) | Q(description__icontains=word) | Q(creator__icontains=word) | Q(contributor__icontains=word) | Q(subject__icontains=word) | Q(disciplines__nom__icontains=word) | - Q(regions__nom__icontains=word) | Q(pays__nom__icontains=word)) + Q(regions__nom__icontains=word) | Q(pays__in=matching_pays)) if q is None: q = part else: @@ -297,7 +306,6 @@ class RecordQuerySet(models.query.QuerySet): select={'score': score_expr}, select_params=score_params ).order_by('-score') - return qs def search_auteur(self, text): @@ -322,11 +330,8 @@ class RecordQuerySet(models.query.QuerySet): """Ne garder que les ressources validées et qui sont soit dans aucun listset ou au moins dans un listset validé.""" qs = self.filter(validated=True) - qs = qs.extra(where=['''((savoirs_record.id NOT IN (SELECT record_id FROM savoirs_record_listsets)) OR - ((SELECT MAX(l.validated) FROM savoirs_listset l - INNER JOIN savoirs_record_listsets rl ON rl.listset_id = l.spec - WHERE rl.record_id = savoirs_record.id) = TRUE))''']) - return qs + qs = qs.filter(Q(listsets__isnull=True) | Q(listsets__validated=True)) + return qs.distinct() class Record(models.Model):