Projet

Général

Profil

0001-general-add-support-for-filtering-on-computed-data-f.patch

Frédéric Péters, 03 août 2021 10:03

Télécharger (4,82 ko)

Voir les différences:

Subject: [PATCH] general: add support for filtering on computed data fields
 (#55891)

 tests/form_pages/test_computed_field.py | 51 +++++++++++++++++++++++++
 wcs/qommon/storage.py                   |  3 +-
 wcs/sql.py                              |  6 ++-
 wcs/variables.py                        |  4 +-
 4 files changed, 60 insertions(+), 4 deletions(-)
tests/form_pages/test_computed_field.py
523 523
    resp.forms[0]['f5'].value = '0'
524 524
    resp = resp.forms[0].submit('submit')  # -> validation
525 525
    assert 'You shall not pass.' not in resp.text
526

  
527

  
528
def test_computed_field_usage_in_criteria(pub):
529
    FormDef.wipe()
530
    formdef = FormDef()
531
    formdef.name = 'test'
532
    formdef.fields = [
533
        fields.PageField(
534
            id='0',
535
            label='1st page',
536
            type='page',
537
        ),
538
        fields.ComputedField(
539
            id='1',
540
            label='computed',
541
            varname='computed',
542
            value_template='{{ request.GET.param }}',
543
            freeze_on_initial_value=True,
544
        ),
545
        fields.PageField(
546
            id='2',
547
            label='2nd page',
548
            type='page',
549
        ),
550
        fields.CommentField(
551
            id='3',
552
            label='<p>count with this value: '
553
            '{{form_objects|exclude_self|filter_by:"computed"|filter_value:form_var_computed|count}}</p>',
554
            type='comment',
555
        ),
556
    ]
557
    formdef.store()
558
    formdef.data_class().wipe()
559

  
560
    resp = get_app(pub).get('/test/?param=test')
561
    resp = resp.forms[0].submit('submit')  # -> 2nd page
562
    assert 'count with this value: 0' in resp.text
563
    resp = resp.forms[0].submit('submit')  # -> validation
564
    resp = resp.forms[0].submit('submit').follow()  # -> submit
565
    assert 'The form has been recorded' in resp.text
566

  
567
    resp = get_app(pub).get('/test/?param=test')
568
    resp = resp.forms[0].submit('submit')  # -> 2nd page
569
    assert 'count with this value: 1' in resp.text
570
    resp = resp.forms[0].submit('submit')  # -> validation
571
    resp = resp.forms[0].submit('submit').follow()  # -> submit
572
    assert 'The form has been recorded' in resp.text
573

  
574
    resp = get_app(pub).get('/test/?param=plop')
575
    resp = resp.forms[0].submit('submit')  # -> 2nd page
576
    assert 'count with this value: 0' in resp.text
wcs/qommon/storage.py
139 139

  
140 140

  
141 141
class Criteria:
142
    def __init__(self, attribute, value):
142
    def __init__(self, attribute, value, **kwargs):
143 143
        self.attribute = attribute
144 144
        self.value = value
145 145
        # Python 3 requires comparisons to disparate types, this means we need
......
152 152
            self.typed_none = -sys.maxsize
153 153
        elif isinstance(self.value, time.struct_time):
154 154
            self.typed_none = time.gmtime(-(10 ** 10))  # 1653
155
        self.field = kwargs.get('field')
155 156

  
156 157
    def build_lambda(self):
157 158
        return lambda x: self.op(getattr(x, self.attribute, None) or self.typed_none, self.value)
wcs/sql.py
106 106
    def __init__(self, attribute, value, **kwargs):
107 107
        self.attribute = attribute.replace('-', '_')
108 108
        self.value = value
109
        self.field = kwargs.get('field')
109 110

  
110 111
    def as_sql(self):
111
        return '%s %s %%(c%s)s' % (self.attribute, self.sql_op, id(self.value))
112
        attribute = self.attribute
113
        if self.field and self.field.key == 'computed':
114
            attribute = "%s->>'data'" % self.attribute
115
        return '%s %s %%(c%s)s' % (attribute, self.sql_op, id(self.value))
112 116

  
113 117
    def as_sql_param(self):
114 118
        if isinstance(self.value, datetime.date):
wcs/variables.py
199 199

  
200 200
        field_id = sql.get_field_id(field)
201 201
        if exclude:
202
            criterias = NotEqual(field_id, value)
202
            criterias = NotEqual(field_id, value, field=field)
203 203
        else:
204
            criterias = Equal(field_id, value)
204
            criterias = Equal(field_id, value, field=field)
205 205
        return self._clone(self._criterias + [criterias])
206 206

  
207 207
    def apply_exclude_value(self, value):
208
-