Projet

Général

Profil

0001-misc-implement-customized-date-search-for-birthdate-.patch

Benjamin Dauvergne, 30 juin 2020 21:03

Télécharger (4,21 ko)

Voir les différences:

Subject: [PATCH] misc: implement customized date search for birthdate
 attribute (#44656)

 src/authentic2/attribute_kinds.py      | 16 +++++++++++++++-
 src/authentic2/custom_user/managers.py | 17 +++++++++++++++++
 tests/test_api.py                      | 14 ++++++++++++++
 3 files changed, 46 insertions(+), 1 deletion(-)
src/authentic2/attribute_kinds.py
25 25
from django import forms
26 26
from django.core.exceptions import ValidationError
27 27
from django.core.validators import RegexValidator
28
from django.utils import six
28
from django.utils import six, formats
29 29
from django.utils.translation import ugettext_lazy as _, pgettext_lazy
30 30
from django.utils import html
31 31
from django.core.files.storage import default_storage
32
from django.db.models import query
32 33

  
33 34
from django.utils.functional import keep_lazy
34 35

  
......
207 208
    return None
208 209

  
209 210

  
211
def date_free_text_search(term):
212
    for date_format in formats.get_format('DATE_INPUT_FORMATS'):
213
        try:
214
            date = datetime.datetime.strptime(term, date_format).date()
215
            break
216
        except (ValueError, TypeError):
217
            pass
218
    else:
219
        return None
220
    return query.Q(attribute_values__content__exact=date.isoformat())
221

  
222

  
210 223
DEFAULT_ALLOW_BLANK = True
211 224
DEFAULT_MAX_LENGTH = 256
212 225

  
......
251 264
        'serialize': lambda x: x and x.isoformat(),
252 265
        'deserialize': lambda x: x and datetime.datetime.strptime(x, '%Y-%m-%d').date(),
253 266
        'rest_framework_field_class': BirthdateRestField,
267
        'free_text_search': date_free_text_search,
254 268
    },
255 269
    {
256 270
        'label': _('french postcode'),
src/authentic2/custom_user/managers.py
37 37
        searchable_attributes = Attribute.objects.filter(searchable=True)
38 38
        queries = []
39 39
        for term in terms:
40
            q = None
41

  
42
            specific_queries = []
43
            for a in searchable_attributes:
44
                kind = a.get_kind()
45
                free_text_search_function = kind.get('free_text_search')
46
                if free_text_search_function:
47
                    q = free_text_search_function(term)
48
                    if q is not None:
49
                        specific_queries.append(q & models.query.Q(attribute_values__attribute=a))
50

  
51
            # if the term is recognized by some specific attribute type, like a
52
            # date, does not use the later generic matcher
53
            if specific_queries is not None:
54
                queries.append(six.moves.reduce(models.query.Q.__or__, specific_queries))
55
                continue
56

  
40 57
            q = (
41 58
                models.query.Q(username__icontains=term)
42 59
                | models.query.Q(first_name__icontains=term)
tests/test_api.py
1703 1703
    assert len(resp.json['results']) == 2
1704 1704
    resp = app.get('/api/users/', params={'modified__lt': '2019-10-27T02:58:07'})
1705 1705
    assert len(resp.json['results']) == 0
1706

  
1707

  
1708
def test_free_text_search(app, admin, settings):
1709
    settings.LANGUAGE_CODE = 'fr'  # use fr date format
1710

  
1711
    app.authorization = ('Basic', (admin.username, admin.username))
1712
    Attribute.objects.create(kind='birthdate', name='birthdate', label='birthdate', required=False, searchable=True)
1713

  
1714
    user = User.objects.create()
1715
    user.attributes.birthdate = datetime.date(1982, 2, 10)
1716

  
1717
    resp = app.get('/api/users/?q=10/02/1982')
1718
    assert len(resp.json['results']) == 1
1719
    assert resp.json['results'][0]['id'] == user.id
1706
-