#33373 closed New feature (needsinfo)
Support expressions on rhs for __has_keys, __has_any_keys JSONField lookups.
Reported by: | john-parton | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 3.2 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I expected that the right hand side of the has_keys lookup for JSONField could be any expression which returns an array of text, but it appears that only python lists of strings are valid.
I think this is also an issue with 4.0, although I have only tested in on 3.2
Consider the following models.
class ProductVariant(models.Model): product = models.ForeignKey( 'catalog.Product', on_delete=models.PROTECT ) attributes = models.JSONField(_("Attributes"), default=dict) class Product(models.Model): configuration = ArrayField( models.TextField() )
Attempting to eval the queryset
ProductVariant.objects.filter(attributes__has_keys=F("product__configuration"))
results in
TypeError 'Col' object is not iterable
As a workaround, here's what I currently do
# Define the custom function class HasAllKeys(Func): function = None template = '(%(expressions)s)' arg_joiner = ' ?& ' arity = 2 output_field = BooleanField() ProductVariant.objects.alias( attributes_has_configuration_keys=HasAllKeys("attributes", "product__configuration") ).filter( attributes_has_configuration_keys=True )
Change History (2)
comment:1 by , 3 years ago
Resolution: | → needsinfo |
---|---|
Status: | new → closed |
Summary: | Canont use expression as Right Hand Side of JSONField has_keys lookup → Support expressions on rhs for __has_keys, __has_any_keys JSONField lookups. |
Type: | Bug → New feature |
comment:2 by , 3 years ago
Thanks for the feedback.
Examples in documentation aren't necessarily meant to be exhaustive. Obviously it's impractical to give an example for every way a feature can be use.
I do think it's a violation of expectations.
At the very least, I think it would be helpful to update the documentation so that it notes that only iterables of strings are valid values for that transformation.
It sounds like the ?& operator only works on Postgres, and not Oracle or other database backends. Is that right?
Are we amenable to making it work with the Postgres backend, and continuing to produce the current error for the other backends?
Thanks for this ticket. Only
__has_keys
examples with lists are documented, so it's not a bug but a new feature. I'm skeptical, this can be error-prone and tricky to implement for all backends (see discussion). We can reconsider this decision if someone provides PoC with cross-database compatibility.