0001-misc-extend-filter_by-to-work-with-fields-with-non-u.patch
tests/test_formdata.py | ||
---|---|---|
1277 | 1277 |
queryset = lazy_formdata.objects.filter_by('datefield').apply_exclude_value( |
1278 | 1278 |
datetime.date(2018, 7, 31).timetuple() |
1279 | 1279 |
) |
1280 |
assert queryset.count == 1
|
|
1280 |
assert queryset.count == 6 # 1 + 5 null
|
|
1281 | 1281 |
queryset = lazy_formdata.objects.filter_by('datefield').apply_exclude_value( |
1282 | 1282 |
datetime.date(2018, 7, 31) |
1283 | 1283 |
) |
1284 |
assert queryset.count == 1
|
|
1284 |
assert queryset.count == 6
|
|
1285 | 1285 |
queryset = lazy_formdata.objects.filter_by('datefield').apply_exclude_value( |
1286 | 1286 |
datetime.datetime(2018, 7, 31) |
1287 | 1287 |
) |
1288 |
assert queryset.count == 1
|
|
1288 |
assert queryset.count == 6
|
|
1289 | 1289 |
queryset = lazy_formdata.objects.filter_by('datefield').apply_exclude_value('2018-07-31') |
1290 |
assert queryset.count == 1
|
|
1290 |
assert queryset.count == 6
|
|
1291 | 1291 |
queryset = lazy_formdata.objects.filter_by('datefield').apply_exclude_value('still not a date') |
1292 | 1292 |
assert queryset.count == 0 |
1293 | 1293 |
assert pub.loggederror_class.count() == 3 |
... | ... | |
1394 | 1394 |
tmpl = Template('{{form_objects|filter_by:"foo_foo"|exclude_value:form_var_foo_foo|count}}') |
1395 | 1395 |
assert tmpl.render(context) == '4' |
1396 | 1396 |
tmpl = Template('{{form_objects|filter_by:"datefield"|exclude_value:form_var_datefield|count}}') |
1397 |
assert tmpl.render(context) == '1'
|
|
1397 |
assert tmpl.render(context) == '6'
|
|
1398 | 1398 |
tmpl = Template('{{form_objects|filter_by:"boolfield"|exclude_value:form_var_boolfield|count}}') |
1399 | 1399 |
assert tmpl.render(context) == '6' |
1400 | 1400 |
tmpl = Template('{{form_objects|filter_by:"term1"|exclude_value:form_var_term1|count}}') |
... | ... | |
1547 | 1547 |
assert 'not a date' not in LazyFormData(formdata).objects.getlist('datefield') |
1548 | 1548 | |
1549 | 1549 | |
1550 |
def test_lazy_formdata_queryset_filter_non_unique_varname(pub, variable_test_data): |
|
1551 |
lazy_formdata = variable_test_data |
|
1552 |
formdef = lazy_formdata._formdef |
|
1553 |
# modify fields to have foo_foo as varname for both fields[0] and fields[7] |
|
1554 |
assert formdef.fields[7].label == 'string2' |
|
1555 |
formdef.fields[7].varname = 'foo_foo' |
|
1556 |
formdef.store() |
|
1557 | ||
1558 |
data_class = lazy_formdata._formdef.data_class() |
|
1559 |
for i in range(6): |
|
1560 |
formdata = data_class() |
|
1561 |
formdata.data = {'0': 'bar', '6': 'baz'} |
|
1562 |
if i == 5: |
|
1563 |
formdata.data['3'] = datetime.date(2018, 8, 31).timetuple() |
|
1564 |
formdata.just_created() |
|
1565 |
formdata.store() |
|
1566 |
formdatas = [] |
|
1567 |
for _ in range(4): |
|
1568 |
formdata = data_class() |
|
1569 |
formdata.data = { |
|
1570 |
'0': 'foo', |
|
1571 |
} |
|
1572 |
formdata.just_created() |
|
1573 |
formdata.jump_status('finished') |
|
1574 |
formdata.store() |
|
1575 |
formdatas.append(formdata) |
|
1576 | ||
1577 |
context = pub.substitutions.get_context_variables(mode='lazy') |
|
1578 |
tmpl = Template('{{form_objects|filter_by:"foo_foo"|filter_value:"bar"|count}}') |
|
1579 |
assert tmpl.render(context) == '7' |
|
1580 |
tmpl = Template('{{form_objects|filter_by:"foo_foo"|filter_value:"other"|count}}') |
|
1581 |
assert tmpl.render(context) == '1' |
|
1582 |
tmpl = Template('{{form_objects|filter_by:"foo_foo"|filter_value:"baz"|count}}') |
|
1583 |
assert tmpl.render(context) == '6' |
|
1584 |
tmpl = Template('{{form_objects|filter_by:"foo_foo"|exclude_value:"bar"|count}}') |
|
1585 |
assert tmpl.render(context) == '4' # 11 - 7 |
|
1586 | ||
1587 |
for formdata in formdatas[:-1]: |
|
1588 |
formdata.data['6'] = 'bar' |
|
1589 |
formdata.store() |
|
1590 | ||
1591 |
tmpl = Template('{{form_objects|filter_by:"foo_foo"|exclude_value:"bar"|count}}') |
|
1592 |
assert tmpl.render(context) == '1' |
|
1593 | ||
1594 | ||
1550 | 1595 |
def test_lazy_formdata_queryset_get_from_first(pub, variable_test_data): |
1551 | 1596 |
context = pub.substitutions.get_context_variables(mode='lazy') |
1552 | 1597 |
del context['form'] # remove actual form from context |
wcs/variables.py | ||
---|---|---|
26 | 26 |
from .formdef import FormDef |
27 | 27 |
from .qommon import _, force_str, misc |
28 | 28 |
from .qommon.evalutils import make_datetime |
29 |
from .qommon.storage import Equal, Intersects, Not, NotEqual, Null, Or |
|
29 |
from .qommon.storage import And, Equal, Intersects, Not, NotEqual, Null, Or
|
|
30 | 30 |
from .qommon.substitution import CompatibilityNamesDict |
31 | 31 |
from .qommon.templatetags.qommon import parse_datetime |
32 | 32 | |
... | ... | |
175 | 175 |
def filter_by_number(self, value): |
176 | 176 |
return self._clone(self._criterias + [Equal('id_display', str(value))]) |
177 | 177 | |
178 |
def get_field(self, key): |
|
178 |
def get_fields(self, key):
|
|
179 | 179 |
for field in self._formdef.get_all_fields(): |
180 | 180 |
if getattr(field, 'varname', None) == key: |
181 |
return field |
|
181 |
yield field |
|
182 | ||
183 |
def get_field(self, key): |
|
184 |
for field in self.get_fields(key): |
|
185 |
return field |
|
182 | 186 | |
183 | 187 |
def apply_filter_value(self, value, exclude=False): |
184 | 188 |
assert self.pending_attr |
185 | 189 | |
186 |
field = self.get_field(self.pending_attr)
|
|
187 |
if field is None:
|
|
190 |
fields = list(self.get_fields(self.pending_attr))
|
|
191 |
if not fields:
|
|
188 | 192 |
get_publisher().record_error( |
189 | 193 |
_('Invalid filter "%s"') % self.pending_attr, formdata=self._formdata |
190 | 194 |
) |
191 | 195 |
return self.none() |
192 | 196 | |
193 |
if field.convert_value_from_anything: |
|
197 |
if fields[0].convert_value_from_anything: |
|
198 |
# consider all fields with same varname are of the same type |
|
199 |
# (it should definitely be) |
|
194 | 200 |
try: |
195 |
value = field.convert_value_from_anything(value) |
|
201 |
value = fields[0].convert_value_from_anything(value)
|
|
196 | 202 |
except (ValueError, AttributeError): |
197 | 203 |
get_publisher().record_error( |
198 | 204 |
_('Invalid value "%s" for filter "%s"') % (value, self.pending_attr), |
... | ... | |
202 | 208 | |
203 | 209 |
from wcs import sql |
204 | 210 | |
205 |
field_id = sql.get_field_id(field) |
|
206 |
if isinstance(value, list): |
|
207 |
criterias = Intersects(field_id, value, field=field) |
|
208 |
else: |
|
209 |
criterias = Equal(field_id, value, field=field) |
|
211 |
criterias = [] |
|
212 |
for field in fields: |
|
213 |
field_id = sql.get_field_id(field) |
|
214 |
if isinstance(value, list): |
|
215 |
criteria = Intersects(field_id, value, field=field) |
|
216 |
if exclude: |
|
217 |
criteria = Not(criteria) |
|
218 |
elif exclude: |
|
219 |
criteria = Or([NotEqual(field_id, value, field=field), Null(field_id)]) |
|
220 |
else: |
|
221 |
criteria = Equal(field_id, value, field=field) |
|
222 |
criterias.append(criteria) |
|
210 | 223 | |
211 |
if exclude: |
|
212 |
criterias = Not(criterias) |
|
224 |
if len(criterias) > 1: |
|
225 |
if exclude: |
|
226 |
criterias = [And(criterias)] |
|
227 |
else: |
|
228 |
criterias = [Or(criterias)] |
|
213 | 229 | |
214 |
return self._clone(self._criterias + [criterias])
|
|
230 |
return self._clone(self._criterias + criterias)
|
|
215 | 231 | |
216 | 232 |
def apply_exclude_value(self, value): |
217 | 233 |
return self.apply_filter_value(value, exclude=True) |
218 |
- |