[Solved] QueryExpression modulo of float value

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

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.

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 … :frowning:

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