Hi,
I have JSONField and I want to know, if key (which has a number value) is an integer.
In the beginning, I checked all this in a python function … which … as we know … is not the best way. To do this I checked if value % 1 == 0.0
Since QueryExpression (Query Expressions | Django documentation | Django ) should support modulo I thought, I can convert this into a query.
>>> instances.filter(my_json__my_key__isnull= False}).annotate(mod_1=ExpressionWrapper(F("my_json__my_key") % 1, output_field=FloatField()), value=F("my_json__my_key")).values("my_json__my_key", "mod_1", "value")
<QuerySet [{'my_json__my_key': 2.5, 'mod_1': 0.0, 'value': 2.5}]>
But as you can see, the annotation mod_1=F("my_json__my_key") % 1
returns 0
although 2.5 % 1 = 0.5
.
Why does this not work?
Best regards
anefta
August 19, 2024, 11:23am
2
HarryKane:
my_json__my_key"
Is that an integer always?
It is always a number (float), therefore I am sure. But I want to know if it actually is an integer.
anefta
August 19, 2024, 11:38am
4
So, you want to perform modulo operation to a number that ‘maybe’ could be an integer?! I think you have to ensure that always must be integer or float. Perhaps the math.fmod function could help you. math — Mathematical functions — Python 3.12.5 documentation
In python 3.12 at least I can apply modulo (%
) on a float:
>>>2.5 % 1
0.5
and I get the remaining, and therefore I can tell if it is an integer (value % 1 == 0
) or if it is a float (value % 1 != 0
),
I tested a query in SQLite:
select 2.5 % 1
0
therefore it seems to be no surprise that this does not work …
I changed my query now
>>> instances_with_non_integer_values = instances.filter(my_json__my_key__isnull= False).annotate(int_value=Cast("my_json__my_key", output_field=IntegerField())).annotate(diff=ExpressionWrapper(F("my_json__my_key")-F("int_value"), output_field=FloatField())).exclude(diff=0)
1 Like