Digamos que tengo un modelo:
class Measurement(models.Model): measurements = JSONField( null=True, blank=True, help_text="Key value pairs for measurements." ) timestamp = models.DateTimeField(auto_now_add=True) class Meta: get_latest_by = "timestamp" Los valores dentro de las measurements son cantidades VARIABLES de pares de valores clave con valores booleanos, pero los valores también pueden ser nulos. Por ejemplo:
{ "a": true, "b": false, // optional "c": null // optional //etc...can be infinite amount of values. }Necesito poder Y esos juntos. Por ejemplo:
result_expression = F("measurements__a") & F("measurements__b") & F("measurements__c") & F("measurement__...")
Obviamente, esto no funciona.
Además, ¿cómo podría anotar los resultados de eso? Measurement.objects.annotate(result=result_expression).values("result")
Donde el resultado aquí debería ser False debido a los valores nulo y Falso.
¿Cómo haría para hacer esto? Soy consciente de que puedo hacer esto puramente con Python. Prefiero no hacer eso. Si hay una forma de Postgres o Django para hacerlo, prefiero hacerlo.
Puede verificar si los tres valores son True con:
Measurement.objects.annotate( measurements__a =True, measurements__b =True, measurements__c =True ).values('result') o puede anotar con una expresión de Case [Django-doc] :
from django.db.models import BooleanField, Case, Value, When Measurement.objects.annotate( result= Case( When( measurements__a =True, measurements__b =True, measurements__c =True, value=Value(True) ), default=Value(False), output_field=BooleanField() ) ).values('result')Para un número variable de claves, podemos usar el desempaquetado del diccionario :
from django.db.models import BooleanField, Case, Value, When items = ['a', 'b', 'c'] Measurement.objects.annotate( result= Case( When( **{f'measurements__{k}': True for k in items } , value=Value(True) ), default=Value(False), output_field=BooleanField() ) ).values('result')