lstephan's suggestions

This commit is contained in:
Martin Pépin 2020-05-07 15:44:37 +02:00
parent b1d8bb04c4
commit 3b0d4ba58f

View file

@ -15,7 +15,7 @@ else:
class SearchUnit: class SearchUnit:
"""Base class for all the search utilities. """Base class for all the search utilities.
A search unit should implement a ``search`` method taking a list of keywords as A search unit should implement a `search` method taking a list of keywords as
argument and returning an iterable of search results. argument and returning an iterable of search results.
""" """
@ -34,8 +34,8 @@ class SearchUnit:
class ModelSearch(SearchUnit): class ModelSearch(SearchUnit):
"""Basic search engine for models based on filtering. """Basic search engine for models based on filtering.
The class should be configured through its ``model`` class attribute: the ``search`` 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`` method will return a queryset of instances of this model. The `search_fields`
attributes indicates which fields to search in. attributes indicates which fields to search in.
Example: Example:
@ -90,7 +90,7 @@ class Select2QuerySetView(ModelSearch, autocomplete.Select2QuerySetView):
# LDAP search # LDAP search
# --- # ---
Clipper = namedtuple("Clipper", "clipper fullname") Clipper = namedtuple("Clipper", ["clipper", "fullname"])
class LDAPSearch(SearchUnit): class LDAPSearch(SearchUnit):
@ -99,6 +99,12 @@ class LDAPSearch(SearchUnit):
search_fields = ["cn", "uid"] search_fields = ["cn", "uid"]
def get_ldap_query(self, keywords): def get_ldap_query(self, keywords):
"""Return a search query with the following semantics:
A Clipper appears in the search results iff all of the keywords given as
arguments occur in at least one of the search fields.
"""
# Dumb but safe # Dumb but safe
keywords = filter(str.isalnum, keywords) keywords = filter(str.isalnum, keywords)
@ -115,12 +121,7 @@ class LDAPSearch(SearchUnit):
return "(&{})".format("".join(ldap_filters)) return "(&{})".format("".join(ldap_filters))
def search(self, keywords): def search(self, keywords):
"""Return a list of Clipper objects matching all the keywords. """Return a list of Clipper objects matching all the keywords."""
The semantic of the search is the following: a Clipper appears in the
search results iff all of the keywords given as arguments occur in at least one
of the search fields.
"""
query = self.get_ldap_query(keywords) query = self.get_ldap_query(keywords)
@ -140,17 +141,17 @@ class LDAPSearch(SearchUnit):
class Compose: class Compose:
"""Search with several units and remove duplicate results. """Search with several units and remove duplicate results.
The ``search_units`` class attribute should be a list of tuples of the form ``(name, The `search_units` class attribute should be a list of tuples of the form `(name,
uniq_key, search_unit)``. uniq_key, search_unit)`.
The ``search`` method produces a dictionnary whose keys are the ``name``s given in The `search` method produces a dictionary whose keys are the `name`s given in
``search_units`` and whose values are iterables produced by the different search `search_units` and whose values are iterables produced by the different search
units. units.
The ``uniq_key``s are used to remove duplicates: for instance, say that search unit The `uniq_key`s are used to remove duplicates: for instance, say that search unit
1 has ``uniq_key = "username"`` and search unit 2 has ``uniq_key = "clipper"``, then 1 has `uniq_key = "username"` and search unit 2 has `uniq_key = "clipper"`, then
search results from unit 2 whose ``.clipper`` attribute is equal to the search results from unit 2 whose `.clipper` attribute is equal to the
``.username`` attribute of some result from unit 1 are omitted. `.username` attribute of some result from unit 1 are omitted.
Typical Example: Typical Example: