Projet

Général

Profil

0001-variables-handle-filtering-lists-by-any-of-values-56.patch

Serghei Mihai (congés, retour 15/05), 03 septembre 2021 12:00

Télécharger (4,77 ko)

Voir les différences:

Subject: [PATCH] variables: handle filtering lists by any of values (#56089)

 tests/test_formdata.py | 24 ++++++++++++++++++++++--
 wcs/qommon/storage.py  | 17 +++++++++++++++++
 wcs/variables.py       | 14 +++++++++++---
 3 files changed, 50 insertions(+), 5 deletions(-)
tests/test_formdata.py
1567 1567
    formdef.fields = [
1568 1568
        fields.StringField(id='1', label='Test', type='string', varname='foo'),
1569 1569
        fields.StringField(id='2', label='key', type='string', varname='key'),
1570
        fields.ItemsField(id='3', label='Items', type='items', varname='items'),
1570 1571
    ]
1571 1572
    formdef.store()
1572 1573
    formdef.data_class().wipe()
1573 1574
    for i in range(6):
1574 1575
        formdata = formdef.data_class()()
1575
        formdata.data = {'1': 'bar', '2': str(i)}
1576
        formdata.data = {'1': 'bar', '2': str(i), '3': [str(i % 2), str(i % 3)]}
1576 1577
        formdata.just_created()
1577 1578
        formdata.store()
1578 1579
    for i in range(4):
1579 1580
        formdata = formdef.data_class()()
1580
        formdata.data = {'1': 'foo', '2': str(i + 6)}
1581
        formdata.data = {'1': 'foo', '2': str(i + 6), '3': [str(i)]}
1581 1582
        formdata.just_created()
1582 1583
        formdata.jump_status('finished')
1583 1584
        formdata.store()
......
1595 1596
    tmpl = Template('{{forms|objects:"foobarlazy"|filter_by:"foo"|filter_value:"bar"|count}}')
1596 1597
    assert tmpl.render(context) == '6'
1597 1598

  
1599
    # filter value by multiple valued field
1600
    tmpl = Template('{{forms|objects:"foobarlazy"|filter_by:"items"|filter_value:"3"|count}}')
1601
    assert tmpl.render(context) == '1'
1602

  
1603
    tmpl = Template('{{forms|objects:"foobarlazy"|filter_by:"items"|filter_value:"2"|count}}')
1604
    assert tmpl.render(context) == '3'
1605

  
1606
    tmpl = Template('{{forms|objects:"foobarlazy"|filter_by:"items"|filter_value:"1|2"|count}}')
1607
    assert tmpl.render(context) == '7'
1608

  
1609
    tmpl = Template('{{forms|objects:"foobarlazy"|filter_by:"items"|filter_value:"6"|count}}')
1610
    assert tmpl.render(context) == '0'
1611

  
1612
    tmpl = Template('{{forms|objects:"foobarlazy"|filter_by:"items"|exclude_value:"1|2"|count}}')
1613
    assert tmpl.render(context) == '3'
1614

  
1615
    tmpl = Template('{{forms|objects:"foobarlazy"|filter_by:"items"|exclude_value:"6"|count}}')
1616
    assert tmpl.render(context) == '10'
1617

  
1598 1618
    pub.custom_view_class.wipe()
1599 1619

  
1600 1620
    custom_view1 = pub.custom_view_class()
wcs/qommon/storage.py
216 216
        return func
217 217

  
218 218

  
219
class NotIntersects(Criteria):
220
    def build_lambda(self):
221
        value = set(self.value)
222

  
223
        def func(x):
224
            try:
225
                print(value)
226
                print(set(getattr(x, self.attribute, [])))
227
                return value.isdisjoint(set(getattr(x, self.attribute, []) or []))
228
            except KeyError:
229
                # this may happen if used to check a formdata field that didn't
230
                # exist when the formdata was created.
231
                return False
232

  
233
        return func
234

  
235

  
219 236
class Or(Criteria):
220 237
    def __init__(self, criterias, **kwargs):
221 238
        self.criterias = criterias
wcs/variables.py
25 25
from .formdef import FormDef
26 26
from .qommon import _, force_str, misc
27 27
from .qommon.evalutils import make_datetime
28
from .qommon.storage import Equal, NotEqual, Null, Or
28
from .qommon.storage import Equal, Intersects, NotEqual, NotIntersects, Null, Or
29 29
from .qommon.substitution import CompatibilityNamesDict
30 30
from .qommon.templatetags.qommon import parse_datetime
31 31

  
......
202 202
        from wcs import sql
203 203

  
204 204
        field_id = sql.get_field_id(field)
205

  
205 206
        if exclude:
206
            criterias = NotEqual(field_id, value, field=field)
207
            if isinstance(value, list):
208
                criterias = NotIntersects(field_id, value, field=field)
209
            else:
210
                criterias = NotEqual(field_id, value, field=field)
207 211
        else:
208
            criterias = Equal(field_id, value, field=field)
212
            if isinstance(value, list):
213
                criterias = Intersects(field_id, value, field=field)
214
            else:
215
                criterias = Equal(field_id, value, field=field)
216

  
209 217
        return self._clone(self._criterias + [criterias])
210 218

  
211 219
    def apply_exclude_value(self, value):
212
-