kpsul/kfet/autocomplete.py
Basile Clement f59e868793 Ajoute get_queryset dans ModelSearch
Quand on utilise les vues d'auto-complétion, on a la possibilité de
configurer des filtres avec `get_queryset_filter`, mais pas d'autres
transformations sur le queryset.  Notamment, cela signifie que pour les
vues qui utilisent des `ForeignKey`, on ne peut pas spécifier de
`select_related` pour éviter des requêtes inutiles et répétées lors du
rendering des vues.

Ce patch ajoute une méthode `get_queryset`, en suivant la convention
habituelle de Django, permettant cette configuration, et l'utilise pour
appeler `select_related` de façon appropriée dans les vues qui en
bénéficient.

À priori, cela devrait permettre de compenser la potentielle perte de
performance de !469, qui a supprimé les `select_related` lors de la
sélection des participants.
2020-10-23 22:37:03 +02:00

94 lines
2.7 KiB
Python

from django.contrib.auth import get_user_model
from django.db.models import Q
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from shared import autocomplete
User = get_user_model()
class KfetAccountSearch(autocomplete.ModelSearch):
model = User
search_fields = [
"username",
"first_name",
"last_name",
"profile__account_kfet__trigramme",
]
verbose_name = _("Comptes existants")
def get_queryset(self):
return super().get_queryset().select_related("profile__account_kfet")
def get_queryset_filter(self, *args, **kwargs):
qset_filter = super().get_queryset_filter(*args, **kwargs)
qset_filter &= Q(profile__account_kfet__isnull=False)
return qset_filter
def result_verbose_name(self, user):
return "{} ({})".format(user, user.profile.account_kfet.trigramme)
def result_uuid(self, user):
return user.username
class COFMemberSearch(autocomplete.ModelSearch):
model = User
search_fields = ["username", "first_name", "last_name"]
verbose_name = _("Membres du COF")
def get_queryset_filter(self, *args, **kwargs):
qset_filter = super().get_queryset_filter(*args, **kwargs)
qset_filter &= Q(profile__account_kfet__isnull=True) & Q(profile__is_cof=True)
return qset_filter
def result_uuid(self, user):
return user.username
def result_link(self, user):
return reverse("kfet.account.create.fromuser", args=(user.username,))
class OthersSearch(autocomplete.ModelSearch):
model = User
search_fields = ["username", "first_name", "last_name"]
verbose_name = _("Non-membres du COF")
def get_queryset_filter(self, *args, **kwargs):
qset_filter = super().get_queryset_filter(*args, **kwargs)
qset_filter &= Q(profile__account_kfet__isnull=True) & Q(profile__is_cof=False)
return qset_filter
def result_uuid(self, user):
return user.username
def result_link(self, user):
return reverse("kfet.account.create.fromuser", args=(user.username,))
class KfetLDAPSearch(autocomplete.LDAPSearch):
def result_link(self, clipper):
return reverse(
"kfet.account.create.fromclipper", args=(clipper.clipper, clipper.fullname)
)
class KfetAutocomplete(autocomplete.Compose):
search_units = [
("kfet", KfetAccountSearch()),
("users_cof", COFMemberSearch()),
("users_notcof", OthersSearch()),
("clippers", KfetLDAPSearch()),
]
kfet_autocomplete = KfetAutocomplete()
class KfetAccountOnlyAutocomplete(autocomplete.Compose):
search_units = [("kfet", KfetAccountSearch())]
kfet_account_only_autocomplete = KfetAccountOnlyAutocomplete()