forked from DGNum/gestioCOF
Autocompletion refactoring + generic view
This commit is contained in:
parent
637572ab58
commit
4d96d2c645
21 changed files with 379 additions and 268 deletions
|
@ -1,10 +1,9 @@
|
|||
from django.contrib.auth import get_user_model
|
||||
from django.db.models import Q
|
||||
from django.http import Http404
|
||||
from django.views.generic import TemplateView
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from gestioncof.decorators import buro_required
|
||||
from shared.views import autocomplete
|
||||
from shared import autocomplete
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
@ -12,45 +11,48 @@ User = get_user_model()
|
|||
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__is_cof=True)
|
||||
return qset_filter
|
||||
|
||||
def result_uuid(self, user):
|
||||
return user.username
|
||||
|
||||
def result_link(self, user):
|
||||
return reverse("user-registration", args=(user.username,))
|
||||
|
||||
|
||||
class COFOthersSearch(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__is_cof=False)
|
||||
return qset_filter
|
||||
|
||||
def result_uuid(self, user):
|
||||
return user.username
|
||||
|
||||
def result_link(self, user):
|
||||
return reverse("user-registration", args=(user.username,))
|
||||
|
||||
|
||||
class COFLDAPSearch(autocomplete.LDAPSearch):
|
||||
def result_link(self, clipper):
|
||||
return reverse("clipper-registration", args=(clipper.clipper, clipper.fullname))
|
||||
|
||||
|
||||
class COFSearch(autocomplete.Compose):
|
||||
search_units = [
|
||||
("members", "username", COFMemberSearch),
|
||||
("others", "username", COFOthersSearch),
|
||||
("clippers", "clipper", autocomplete.LDAPSearch),
|
||||
("members", COFMemberSearch()),
|
||||
("others", COFOthersSearch()),
|
||||
("clippers", COFLDAPSearch()),
|
||||
]
|
||||
|
||||
|
||||
cof_search = COFSearch()
|
||||
|
||||
|
||||
class AutocompleteView(TemplateView):
|
||||
template_name = "gestioncof/search_results.html"
|
||||
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
ctx = super().get_context_data(*args, **kwargs)
|
||||
if "q" not in self.request.GET:
|
||||
raise Http404
|
||||
q = self.request.GET["q"]
|
||||
ctx["q"] = q
|
||||
ctx.update(cof_search.search(q.split()))
|
||||
return ctx
|
||||
|
||||
|
||||
autocomplete = buro_required(AutocompleteView.as_view())
|
||||
|
|
|
@ -1,56 +1,21 @@
|
|||
{% load search_utils %}
|
||||
{% extends "shared/search_results.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
<ul>
|
||||
{% if members %}
|
||||
<li class="autocomplete-header">Membres</li>
|
||||
{% for user in members %}
|
||||
{% if forloop.counter < 5 %}
|
||||
<li class="autocomplete-value">
|
||||
<a href="{% url "user-registration" user.username %}">
|
||||
{{ user|highlight_user:q }}
|
||||
</a>
|
||||
</li>
|
||||
{% elif forloop.counter == 5 %}
|
||||
<li class="autocomplete-more">...</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if others %}
|
||||
<li class="autocomplete-header">Non-membres</li>
|
||||
{% for user in others %}
|
||||
{% if forloop.counter < 5 %}
|
||||
<li class="autocomplete-value">
|
||||
<a href="{% url "user-registration" user.username %}">
|
||||
{{ user|highlight_user:q }}
|
||||
</a>
|
||||
</li>
|
||||
{% elif forloop.counter == 5 %}
|
||||
<li class="autocomplete-more">...</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if clippers %}
|
||||
<li class="autocomplete-header">Utilisateurs <tt>clipper</tt></li>
|
||||
{% for clipper in clippers %}
|
||||
{% if forloop.counter < 5 %}
|
||||
<li class="autocomplete-value">
|
||||
<a href="{% url "clipper-registration" clipper.clipper clipper.fullname %}">
|
||||
{{ clipper|highlight_clipper:q }}
|
||||
</a>
|
||||
</li>
|
||||
{% elif forloop.counter == 5 %}
|
||||
<li class="autocomplete-more">...</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if total %}
|
||||
<li class="autocomplete-header">Pas dans la liste ?</li>
|
||||
{% else %}
|
||||
<li class="autocomplete-header">Aucune correspondance trouvée</li>
|
||||
{% endif %}
|
||||
|
||||
<li><a href="{% url "empty-registration" %}">Créer un compte</a></li>
|
||||
</ul>
|
||||
{% block extra_section %}
|
||||
<li class="autocomplete-header">
|
||||
{% if not results %}
|
||||
<span class="autocomplete-item">
|
||||
{% trans "Aucune correspondance trouvée" %}
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="autocomplete-item">
|
||||
{% trans "Pas dans la liste ?" %}
|
||||
</span>
|
||||
{% endif %}
|
||||
</li>
|
||||
<li class="autocomplete-new">
|
||||
<a class="autocomplete-item" href="{% url "empty-registration" %}">
|
||||
{% trans "Créer un compte" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endblock %}
|
||||
|
|
|
@ -16,8 +16,8 @@ from django.urls import reverse
|
|||
from bda.models import Salle, Tirage
|
||||
from gestioncof.models import CalendarSubscription, Club, Event, Survey, SurveyAnswer
|
||||
from gestioncof.tests.mixins import MegaHelperMixin, ViewTestCaseMixin
|
||||
from shared.autocomplete import Clipper, LDAPSearch
|
||||
from shared.tests.mixins import CSVResponseMixin, ICalMixin, MockLDAPMixin
|
||||
from shared.views.autocomplete import Clipper
|
||||
|
||||
from .utils import create_member, create_root, create_user
|
||||
|
||||
|
@ -290,14 +290,30 @@ class RegistrationAutocompleteViewTests(MockLDAPMixin, ViewTestCaseMixin, TestCa
|
|||
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
||||
def extract(section):
|
||||
return [r.verbose_name for r in section.entries]
|
||||
|
||||
others = []
|
||||
members = []
|
||||
clippers = []
|
||||
for section in r.context["results"]:
|
||||
if section.name == "others":
|
||||
others = extract(section)
|
||||
elif section.name == "members":
|
||||
members = extract(section)
|
||||
elif section.name == "clippers":
|
||||
clippers = extract(section)
|
||||
else:
|
||||
raise ValueError("Unexpected section name: {}".format(section.name))
|
||||
|
||||
self.assertQuerysetEqual(
|
||||
r.context["others"], map(repr, expected_others), ordered=False
|
||||
others, map(str, expected_others), ordered=False, transform=str
|
||||
)
|
||||
self.assertQuerysetEqual(
|
||||
r.context["members"], map(repr, expected_members), ordered=False,
|
||||
members, map(str, expected_members), ordered=False, transform=str
|
||||
)
|
||||
self.assertCountEqual(
|
||||
map(str, r.context["clippers"]), map(str, expected_clippers)
|
||||
self.assertSetEqual(
|
||||
set(clippers), set(map(LDAPSearch().result_verbose_name, expected_clippers))
|
||||
)
|
||||
|
||||
def test_username(self):
|
||||
|
|
|
@ -25,6 +25,7 @@ from django_cas_ng.views import LogoutView as CasLogoutView
|
|||
from icalendar import Calendar, Event as Vevent
|
||||
|
||||
from bda.models import Spectacle, Tirage
|
||||
from gestioncof.autocomplete import cof_search
|
||||
from gestioncof.decorators import buro_required, cof_required
|
||||
from gestioncof.forms import (
|
||||
CalendarForm,
|
||||
|
@ -58,7 +59,7 @@ from gestioncof.models import (
|
|||
SurveyQuestion,
|
||||
SurveyQuestionAnswer,
|
||||
)
|
||||
from shared.views.autocomplete import Select2QuerySetView
|
||||
from shared.views import AutocompleteView, Select2QuerySetView
|
||||
|
||||
|
||||
class HomeView(LoginRequiredMixin, TemplateView):
|
||||
|
@ -942,9 +943,18 @@ class ConfigUpdate(FormView):
|
|||
##
|
||||
|
||||
|
||||
# For the admin site
|
||||
class UserAutocomplete(Select2QuerySetView):
|
||||
model = User
|
||||
search_fields = ("username", "first_name", "last_name")
|
||||
|
||||
|
||||
user_autocomplete = buro_required(UserAutocomplete.as_view())
|
||||
|
||||
|
||||
class COFAutocompleteView(AutocompleteView):
|
||||
template_name = "gestioncof/search_results.html"
|
||||
search_composer = cof_search
|
||||
|
||||
|
||||
registration_autocomplete = buro_required(COFAutocompleteView.as_view())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue