#33344: Define bounds transform for discrete postgres range fields
-------------------------------------+-------------------------------------
               Reporter:  Vidir      |          Owner:  (none)
  Valberg Gudmundsson                |
                   Type:  New        |         Status:  new
  feature                            |
              Component:             |        Version:  dev
  contrib.postgres                   |
               Severity:  Normal     |       Keywords:
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 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 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>
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/050.a7efee71680c6f66fa03a7f99dc5d4cc%40djangoproject.com.

Reply via email to