#30711: Document django.contrib.postgres.fields.hstore.KeyTransform.
--------------------------------------+------------------------------------
Reporter: Gustav Eiman | Owner: nobody
Type: Cleanup/optimization | Status: new
Component: Documentation | Version: master
Severity: Normal | Resolution:
Keywords: HStoreField F | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------
Changes (by felixxm):
* component: contrib.postgres => Documentation
* owner: (none) => nobody
* type: New feature => Cleanup/optimization
* stage: Unreviewed => Accepted
Old description:
> 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
New description:
Document `django.contrib.postgres.fields.hstore.KeyTransform` in the
[https://docs.djangoproject.com/en/dev/ref/contrib/postgres/fields/#hstorefield
HStoreField documentation] that can be used on the right hand side of a
filter or an annotation.
--
Comment:
I changed ticket description, thanks!
--
Ticket URL: <https://code.djangoproject.com/ticket/30711#comment:3>
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/066.c6d1ede2f09c230fca38b38c2c105102%40djangoproject.com.