J'ai aussi essayé d'optimiser les requêtes un peu...
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:
# 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)
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ç]')
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')
class EvenementQuerySet(models.query.QuerySet):
def search(self, text):
- qs = self
q = None
for word in text.split():
part = (Q(titre__icontains=word) |
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
# 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:
select={'score': score_expr},
select_params=score_params
).order_by('-score')
-
return qs
def search_auteur(self, text):
"""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):