forked from DGNum/gestioCOF
Merge branch 'kerl/merge_shared_utils' into 'master'
Préparation de la vue d'autocompletion pour l'intégration du BDS See merge request klub-dev-ens/gestioCOF!401
This commit is contained in:
commit
5298a19667
8 changed files with 62 additions and 31 deletions
|
@ -61,9 +61,9 @@ linters:
|
||||||
- pip install --upgrade black isort flake8
|
- pip install --upgrade black isort flake8
|
||||||
script:
|
script:
|
||||||
- black --check .
|
- black --check .
|
||||||
- isort --recursive --check-only --diff bda bds clubs cof events gestioncof kfet petitscours provisioning shared utils
|
- isort --recursive --check-only --diff bda bds clubs cof events gestioncof kfet petitscours provisioning shared
|
||||||
# Print errors only
|
# Print errors only
|
||||||
- flake8 --exit-zero bda bds clubs cof events gestioncof kfet petitscours provisioning shared utils
|
- flake8 --exit-zero bda bds clubs cof events gestioncof kfet petitscours provisioning shared
|
||||||
cache:
|
cache:
|
||||||
key: linters
|
key: linters
|
||||||
paths:
|
paths:
|
||||||
|
|
|
@ -42,7 +42,7 @@ from bda.models import (
|
||||||
Tirage,
|
Tirage,
|
||||||
)
|
)
|
||||||
from gestioncof.decorators import BuroRequiredMixin, buro_required, cof_required
|
from gestioncof.decorators import BuroRequiredMixin, buro_required, cof_required
|
||||||
from utils.views.autocomplete import Select2QuerySetView
|
from shared.views.autocomplete import Select2QuerySetView
|
||||||
|
|
||||||
|
|
||||||
@cof_required
|
@cof_required
|
||||||
|
|
|
@ -58,7 +58,7 @@ from gestioncof.models import (
|
||||||
SurveyQuestion,
|
SurveyQuestion,
|
||||||
SurveyQuestionAnswer,
|
SurveyQuestionAnswer,
|
||||||
)
|
)
|
||||||
from utils.views.autocomplete import Select2QuerySetView
|
from shared.views.autocomplete import Select2QuerySetView
|
||||||
|
|
||||||
|
|
||||||
class HomeView(LoginRequiredMixin, TemplateView):
|
class HomeView(LoginRequiredMixin, TemplateView):
|
||||||
|
|
|
@ -9,7 +9,6 @@ source =
|
||||||
kfet
|
kfet
|
||||||
petitscours
|
petitscours
|
||||||
shared
|
shared
|
||||||
utils
|
|
||||||
omit =
|
omit =
|
||||||
*migrations*
|
*migrations*
|
||||||
*test*.py
|
*test*.py
|
||||||
|
@ -37,7 +36,7 @@ default_section = THIRDPARTY
|
||||||
force_grid_wrap = 0
|
force_grid_wrap = 0
|
||||||
include_trailing_comma = true
|
include_trailing_comma = true
|
||||||
known_django = django
|
known_django = django
|
||||||
known_first_party = bda,bds,clubs,cof,events,gestioncof,kfet,petitscours,shared,utils
|
known_first_party = bda,bds,clubs,cof,events,gestioncof,kfet,petitscours,shared
|
||||||
line_length = 88
|
line_length = 88
|
||||||
multi_line_output = 3
|
multi_line_output = 3
|
||||||
not_skip = __init__.py
|
not_skip = __init__.py
|
||||||
|
|
57
shared/views/autocomplete.py
Normal file
57
shared/views/autocomplete.py
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
from dal import autocomplete
|
||||||
|
from django.db.models import Q
|
||||||
|
|
||||||
|
|
||||||
|
class ModelSearch:
|
||||||
|
"""Basic search engine for models based on filtering.
|
||||||
|
|
||||||
|
The class should be configured through its ``model`` class attribute: the ``search``
|
||||||
|
method will return a queryset of instances of this model. The ``search_fields``
|
||||||
|
attributes indicates which fields to search in.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
>>> from django.contrib.auth.models import User
|
||||||
|
>>>
|
||||||
|
>>> class UserSearch(ModelSearch):
|
||||||
|
... model = User
|
||||||
|
... search_fields = ["username", "first_name", "last_name"]
|
||||||
|
>>>
|
||||||
|
>>> user_search = UserSearch() # has type ModelSearch[User]
|
||||||
|
>>> user_search.search(["toto", "foo"]) # returns a queryset of Users
|
||||||
|
"""
|
||||||
|
|
||||||
|
model = None
|
||||||
|
search_fields = []
|
||||||
|
|
||||||
|
def get_queryset_filter(self, keywords):
|
||||||
|
filter_q = Q()
|
||||||
|
|
||||||
|
if not keywords:
|
||||||
|
return filter_q
|
||||||
|
|
||||||
|
for keyword in keywords:
|
||||||
|
kw_filter = Q()
|
||||||
|
for field in self.search_fields:
|
||||||
|
kw_filter |= Q(**{"{}__icontains".format(field): keyword})
|
||||||
|
filter_q &= kw_filter
|
||||||
|
|
||||||
|
return filter_q
|
||||||
|
|
||||||
|
def search(self, keywords):
|
||||||
|
"""Returns the queryset of model instances matching all the keywords.
|
||||||
|
|
||||||
|
The semantic of the search is the following: a model instance appears in the
|
||||||
|
search results iff all of the keywords given as arguments occur in at least one
|
||||||
|
of the search fields.
|
||||||
|
"""
|
||||||
|
|
||||||
|
return self.model.objects.filter(self.get_queryset_filter(keywords))
|
||||||
|
|
||||||
|
|
||||||
|
class Select2QuerySetView(ModelSearch, autocomplete.Select2QuerySetView):
|
||||||
|
"""Compatibility layer between ModelSearch and Select2QuerySetView."""
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
keywords = self.q.split()
|
||||||
|
return super().search(keywords)
|
|
@ -1,25 +0,0 @@
|
||||||
from dal import autocomplete
|
|
||||||
from django.db.models import Q
|
|
||||||
|
|
||||||
|
|
||||||
class Select2QuerySetView(autocomplete.Select2QuerySetView):
|
|
||||||
model = None
|
|
||||||
search_fields = []
|
|
||||||
|
|
||||||
def get_queryset_filter(self):
|
|
||||||
q = self.q
|
|
||||||
filter_q = Q()
|
|
||||||
|
|
||||||
if not q:
|
|
||||||
return filter_q
|
|
||||||
|
|
||||||
words = q.split()
|
|
||||||
|
|
||||||
for word in words:
|
|
||||||
for field in self.search_fields:
|
|
||||||
filter_q |= Q(**{"{}__icontains".format(field): word})
|
|
||||||
|
|
||||||
return filter_q
|
|
||||||
|
|
||||||
def get_queryset(self):
|
|
||||||
return self.model.objects.filter(self.get_queryset_filter())
|
|
Loading…
Reference in a new issue