#30711: Add HStoreF for F object like querying on HStoreField.
-------------------------------------+-------------------------------------
Reporter: tiptop96 | Owner: (none)
Type: New | Status: new
feature |
Component: | Version: 2.2
contrib.postgres |
Severity: Normal | Keywords: HStoreField F
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
When using F objects for key lookups on HStoreFields it never digs down to
get the keys but unexpectedly returns the entire object.
Lets say we have this model:
{{{
from django.contrib.postgres.fields import HStoreField
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=256)
attributes = HStoreField()
}}}
We then populate it.
{{{
Person.objects.create(name="James", attributes={"age": "30", "height":
"190"})
}}}
Here comes the thing that bothers me. If we try to access either of these
keys the entire attributes cell will be returned.
{{{
p = Person.objects.annotate(length=F("attributes__height"))
p[0].height
>>> {"age": "30", "height": "190"}
}}}
While the expected result would be an error or the value of the height
field, it's not.
I propose either making F objects support these fields or creating a new
type to handle this, a workaround that I'm playing around with myself.
{{{
from django.contrib.postgres.fields.jsonb import KeyTransformFactory
class HStoreF(F):
def resolve_expression(self, query=None, allow_joins=True, reuse=None,
summarize=False, for_save=False):
rhs = super().resolve_expression(query, allow_joins, reuse,
summarize, for_save)
field_list = self.name.split("__")
if field_list[-1] == rhs.target.name:
raise LookupError(
"HStoreF requires a key lookup in order to avoid unexpected
behavior. "
"Please append '__somekey' to '{}'."
.format("__".join(field_list)))
return KeyTransformFactory(field_list[-1])(rhs)
}}}
An issue with this is that updating models with it still wont work. As an
error is raised in {{{Query.resolve_ref()}}} due to the fact that it
interprets the {{{"__"}}} as an attempted join. This could be solved by
using a different lookup separator for keys (maybe relevant for JSONField
to?), but I was unable to successfully implement this.
Similar issue with JSONField: https://code.djangoproject.com/ticket/29769
--
Ticket URL: <https://code.djangoproject.com/ticket/30711>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/051.fe579ab93d5dbcefd98faddf3e89c416%40djangoproject.com.