New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixed #27147 -- Allowed specifying bounds of tuple inputs for non-discrete range fields. #14538
Conversation
Hello @gmcrocetti! Thank you for your contribution 💪 As it's your first contribution be sure to check out the patch review checklist. If you're fixing a ticket from Trac make sure to set the "Has patch" flag and include a link to this PR in the ticket! If you have any design or process questions then you can ask in the Django forum. Welcome aboard ⛵️! |
61f1eb4
to
32a269a
Compare
I'd appreciate any enlightenment on why CI is failing. |
@gmcrocetti not sure you got tox passing tests locally but the error on Jenkins is the following
|
32a269a
to
3be0653
Compare
Yes, |
@gmcrocetti I've seen that you managed to get things working but for the future https://github.com/django/django-docker-box is usually the easiest way to get test running against different backends locally. |
@charettes . I'm not familiar with the django's revision queue. Is there anything else expected from me or you folks handle it now ? |
@gmcrocetti the ticket still has the needs documentation checkbox ticked hence why it doesn't show up in the review queue. Since there's still unanswered questions about the approach to take I'd try to gather feedback from the reporter as well as the folks involved in #10484. If that doesn't yield any result I'd post to the developer mailing list to reach a wider audience. |
@jdufresne , would you like taking a look ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gmcrocetti Thanks for this patch 👍
I could think of two UIs to fix the stated problem:
We can add a
default_bounds
as an argument toRangeField
class, and thus all subclasses. The problem of this approach is that we may add some cutler for discrete ranges. For example, IMO it makes no sense to set adefault_bounds
value for aIntegerRangeField
as it'll always be converted to[)
, cluttering user's experience. Please, let me know if I'm missing something.We can specialize
RangeField
for continuous ranges. With this approach we're preventing misuse.
I'm fine with the 2nd approach, however we should raise TypeError
when a default_bounds
is passed to the RangeField
because it accepts all keyword arguments so folks may not be aware that it's ignored for other types.
DummyRange.objects.create(timestamps=DateTimeTZRange(lower_date, upper_date)) # saved with bounds='[)'
This example is tricky, I'm not sure if we can distinguish that bounds were passed to the DateTimeTZRange
but I would expect default_bounds
to be used in this case.
@felixxm . Thanks a lot for your review !
I'm ok with raising a
Yeah. That's mostly why I was expecting a feedback before writing more code/documentation. # Considering the value is being "intercepted"
from psycopg2.extras import DateTimeTZRange
lower_date = datetime.date(2014, 1, 1)
upper_date = datetime.date(2014, 2, 2)
class DummyRange(models.Model):
timestamps = DateTimeRangeField(blank=True, null=True, default_bounds='[]')
DummyRange.objects.create(timestamps=DateTimeTZRange(lower_date, upper_date)) # OK. saved with bounds='[]'
DummyRange.objects.create(timestamps=DateTimeTZRange(lower_date, upper_date, bounds='(]')) # NOK. saved with bounds=[], but the user thought it was '(]'
DummyRange.objects.create(timestamps=DateTimeTZRange(lower_date, upper_date, bounds='[)')) # NOK. saved with bounds='[]' I agree that it's non-conventional to have this distinction between list and tuples x Range objects. Whoever is using the Range object must be aware that there's a default value for the bounds argument. That's why I assumed the bound attribute must take precedence over
|
@gmcrocetti thanks for working on this issue. I think a perfect addition to this PR would be, let people optionally pass the bounds in the list without importing the psycopg2 range types. Using a different code example: from django.contrib.postgres.fields import DecimalRangeField
from django.db import models
class Offer(models.Model)
"""An offer with a default price range (all non-zero positive decimals)."""
price_range = DecimalRangeField(default=(0, None, '()')) # bounds == '()' as specified
>>> Offer.objects.create(price_range=(0, 150)) # bounds == '[)' as default
>>> Offer.objects.create(price_range=(0, 150, '(]')) # bounds == '(]' as specified
>>> Offer.objects.create(price_range=(0, 150, '-')) # bounds == '[)' as fallback |
This is a separate ticket (see ticket-31872), which I rejected .... |
Thanks for let me know. 👍 |
I don't have an example, but something like this: class RangeField(models.Field):
...
def __init__(self, *args, **kwargs):
if 'default_bounds' in kwargs:
raise TypeError(f"Cannot use 'default_bounds' with {self.__class__.__name__}.") should work.
OK, let's leave it as it is. We can add a note in docs, that |
3be0653
to
6ff0ac0
Compare
7619d8e
to
16be46a
Compare
@felixxm , pushed documentation and left one question regarding the validation of |
d8861ba
to
5b783c1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gmcrocetti Thanks for updates 👍
We should also add release notes (4.1.txt
) and update Range Fields description.
66c9a95
to
ee2fad5
Compare
@felixxm , updated. |
e223a32
to
d8fc54b
Compare
d8fc54b
to
3efe634
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gmcrocetti Thanks for updates 👍 Welcome aboard ⛵
I pushed final edits to docs and tests.
3efe634
to
660f691
Compare
@felixxm , thanks a lot for all the effort. Documentation is pretty clear and thanks for the tests. Just left one |
…h DecimalRangeField in migrations.
…crete range fields.
660f691
to
fc565cb
Compare
This PR fixes #27147.
I could think of two UIs to fix the stated problem:
default_bounds
as an argument toRangeField
class, and thus all subclasses. The problem of this approach is that we may add some cutler for discrete ranges. For example, IMO it makes no sense to set adefault_bounds
value for aIntegerRangeField
as it'll always be converted to[)
, cluttering user's experience. Please, let me know if I'm missing something.RangeField
for continuous ranges. With this approach we're preventing misuse.I implemented approach 2.
I'm following a conservative approach for
default_bounds
. For example:The reasoning behind is that a user knows what's he's doing if he created a
Range
object (Adding a validator sounds like a good idea). I still need to document whichever behavior we choose.Looking forward for feedback before finishing this feature.