0001-sql-use-custom-json-encoder-for-computed-data-storag.patch
tests/form_pages/test_computed_field.py | ||
---|---|---|
1 | 1 |
import datetime |
2 |
import decimal |
|
2 | 3 | |
3 | 4 |
import pytest |
4 | 5 |
from django.utils.timezone import make_aware |
... | ... | |
330 | 331 |
assert formdata.data['1'] == {'foo': 'bar'} |
331 | 332 | |
332 | 333 | |
334 |
def test_computed_field_decimal_data(pub, http_requests): |
|
335 |
FormDef.wipe() |
|
336 | ||
337 |
formdef = FormDef() |
|
338 |
formdef.name = 'test' |
|
339 |
formdef.fields = [ |
|
340 |
fields.ComputedField( |
|
341 |
id='1', |
|
342 |
label='computed', |
|
343 |
varname='computed', |
|
344 |
value_template='{{ "123.45"|decimal }}', |
|
345 |
freeze_on_initial_value=True, |
|
346 |
), |
|
347 |
fields.CommentField(id='2', label='X{{form_var_computed}}Y', type='comment'), |
|
348 |
] |
|
349 |
formdef.store() |
|
350 |
formdef.data_class().wipe() |
|
351 | ||
352 |
resp = get_app(pub).get('/test/') |
|
353 |
assert 'X123.45Y' in resp.text |
|
354 |
resp = resp.forms[0].submit('submit') # -> validation |
|
355 |
resp = resp.forms[0].submit('submit').follow() # -> submit |
|
356 |
assert 'The form has been recorded' in resp.text |
|
357 |
assert formdef.data_class().count() == 1 |
|
358 |
formdata = formdef.data_class().select()[0] |
|
359 |
# pickle storage keeps the typed data but postgresql storage has to convert |
|
360 |
# it to stringfor json storage, hence the casting here: |
|
361 |
assert decimal.Decimal(formdata.data['1']) == decimal.Decimal('123.45') |
|
362 | ||
363 | ||
333 | 364 |
def test_computed_field_usage_in_live_data(pub, http_requests): |
334 | 365 |
FormDef.wipe() |
335 | 366 |
wcs/sql.py | ||
---|---|---|
17 | 17 |
import copy |
18 | 18 |
import datetime |
19 | 19 |
import io |
20 |
import json |
|
20 | 21 |
import re |
21 | 22 |
import time |
22 | 23 |
import unicodedata |
... | ... | |
47 | 48 |
from . import qommon |
48 | 49 |
from .publisher import UnpicklerClass |
49 | 50 |
from .qommon import _, get_cfg |
50 |
from .qommon.misc import strftime |
|
51 |
from .qommon.misc import JSONEncoder, strftime
|
|
51 | 52 |
from .qommon.storage import _take, deep_bytes2str |
52 | 53 |
from .qommon.storage import parse_clause as parse_storage_clause |
53 | 54 |
from .qommon.substitution import invalidate_substitution_cache |
... | ... | |
1700 | 1701 |
if value is not None: |
1701 | 1702 |
# embed value in a dict, so it's never necessary to cast the |
1702 | 1703 |
# value for postgresql |
1703 |
value = {'data': value, '@type': 'computed-data'}
|
|
1704 |
value = {'data': json.loads(JSONEncoder().encode(value)), '@type': 'computed-data'}
|
|
1704 | 1705 |
elif sql_type == 'varchar': |
1705 | 1706 |
assert isinstance(value, str) |
1706 | 1707 |
elif sql_type == 'date': |
1707 |
- |