#33344: Define bounds transform for discrete postgres range fields
-------------------------------------+-------------------------------------
Reporter: Vidir Valberg | Owner: (none)
Gudmundsson |
Type: New feature | Status: new
Component: contrib.postgres | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by Vidir Valberg Gudmundsson:
Old description:
> The fix for https://code.djangoproject.com/ticket/27147 adressed the
> issue of non-discrete range types. Left is the issue of how the ranges
> are "represented" when brought back from the database.
>
> At $WORK we have a model like so:
>
> {{{
> class Foo(models.Model):
> ...
> period = models.DateRangeField()
> }}}
>
>
> The problem arises when we display the periods of multiple `Foo`s. Using
> the default bound of `[)` returned by postgres means that adjacent `Foo`s
> "visually" share a date in the upper of one and lower of the other. We
> could of course handle this ''each time'' we output the value by
> decrementing the upper value. But this is a bit error prone and can lead
> to confusions.
>
> I propose that we add something in the lines of the following to
> `django.contrib.postres.fields.ranges` (heavily inspired by Jakub
> Skałeckis comment at
> https://code.djangoproject.com/ticket/27147#comment:8):
>
> {{{
> class DiscreteRangeField(RangeField):
>
> def __init__(self, *args, bounds_transform=CANONICAL_RANGE_BOUNDS,
> **kwargs):
> if bounds_transform not in ALLOWED_BOUNDS:
> raise ValueError("bounds_transform must be one of '[)', '(]',
> '()', or '[]'.")
> self.bounds_transform = bounds_transform
> super().__init__(*args, **kwargs)
>
> def from_db_value(self, value, expression, connection):
> if value is None:
> return
>
> if self.bounds_transform[0] == "(" and value.lower:
> value._lower = value.lower - self.bounds_transform_unit
>
> if self.bounds_transform[1] == "]" and value.upper:
> value._lower = value.upper - self.bounds_transform_unit
>
> value._bounds = self.bounds_transform
> return value
> }}}
>
> and make `IntegerRangeField`, `BigIntegerRangeField` and `DateRangeField`
> inherit from `DiscreteRangeField`.
>
> I have already written some tests, and if there are no big gotchas to
> this approach I would love to submit a PR in the next couple of days.
New description:
The fix for https://code.djangoproject.com/ticket/27147 adressed the issue
of non-discrete range types. Left is the issue of how the ranges are
"represented" when brought back from the database.
At $WORK we have a model like so:
{{{
class Foo(models.Model):
...
period = models.DateRangeField()
}}}
The problem arises when we display the periods of multiple `Foo`s. Using
the default bound of `[)` returned by postgres means that adjacent `Foo`s
"visually" share a date in the upper of one and lower of the other. We
could of course handle this ''each time'' we output the value by
decrementing the upper value. But this is a bit error prone and can lead
to confusions.
I propose that we add something along the lines of the following to
`django.contrib.postres.fields.ranges` (heavily inspired by Jakub
Skałeckis comment at
https://code.djangoproject.com/ticket/27147#comment:8):
{{{
class DiscreteRangeField(RangeField):
def __init__(self, *args, bounds_transform=CANONICAL_RANGE_BOUNDS,
**kwargs):
if bounds_transform not in ALLOWED_BOUNDS:
raise ValueError("bounds_transform must be one of '[)', '(]',
'()', or '[]'.")
self.bounds_transform = bounds_transform
super().__init__(*args, **kwargs)
def from_db_value(self, value, expression, connection):
if value is None:
return
if self.bounds_transform[0] == "(" and value.lower:
value._lower = value.lower - self.bounds_transform_unit
if self.bounds_transform[1] == "]" and value.upper:
value._lower = value.upper - self.bounds_transform_unit
value._bounds = self.bounds_transform
return value
}}}
and make `IntegerRangeField`, `BigIntegerRangeField` and `DateRangeField`
inherit from `DiscreteRangeField`.
I have already written some tests, and if there are no big gotchas to this
approach I would love to submit a PR in the next couple of days.
--
--
Ticket URL: <https://code.djangoproject.com/ticket/33344#comment:2>
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/065.5f7e054bd4605af8a4ee2500d511f507%40djangoproject.com.