#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.

Reply via email to