Opened 3 years ago
Last modified 3 years ago
#33344 closed New feature
Define bounds transform for discrete postgres range fields — at Initial Version
Reported by: | Vidir Valberg Gudmundsson | Owned by: | |
---|---|---|---|
Component: | contrib.postgres | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
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 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.