#29656: Range Fields do not support blank values via ModelForm
-------------------------------+--------------------------------------
     Reporter:  James Addison  |                    Owner:  nobody
         Type:  Bug            |                   Status:  new
    Component:  Forms          |                  Version:  1.11
     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 James Addison:

Old description:

> The filing of this issue is based on a discussion in IRC (see
> https://botbot.me/freenode/django/2018-08-09/?msg=103129716&page=12 and
> prior messages), followed up by creating a test project to reproduce the
> issue.
>
> Please do correct me if I am misusing range fields.
>
> ----
>
> Saving a modelform with a model's rangefield 2 inputs left empty triggers
> an DB integrity error. I think the culprit lies with `empty_values` not
> containing `['', '']` as a possible empty value. (see the code around
> https://github.com/django/django/blob/1.11.15/django/forms/fields.py#L1026).
>
> '''`self.compress([])` should return the result of `self.range_type(None,
> None)` instead of just `None`.'''
>
> With a view like:
>
> {{{
> def home(request):
>     if request.method == 'POST':
>         form = RangeTestForm(request.POST)
>         if form.is_valid():
>             instance = form.save()
>     else:
>         form = RangeTestForm(request.POST)
>
>     return render(request, 'rangefieldtest/home.html', {'form': form})
> }}}
>
> Form like:
> {{{
> class RangeTestForm(forms.ModelForm):
>     class Meta:
>         model = RangeTest
>         fields = '__all__'
> }}}
>
> and Model like:
> {{{
> from django.contrib.postgres.fields import FloatRangeField
> from psycopg2._range import NumericRange
>
> class RangeTest(models.Model):
>     name = models.CharField(max_length=50, blank=True, default='')
>     age_range = FloatRangeField(blank=True, default=NumericRange)
> }}}
>
> I will attach a sample project demonstrating this (use runserver, load
> the home page, click save)
>

> ----
> psql table definition:
> {{{
>                                   Table "public.rangefieldtest_rangetest"
>   Column   |         Type          |
> Modifiers
> -----------+-----------------------+-----------------------------------------------------------------------
>  id        | integer               | not null default
> nextval('rangefieldtest_rangetest_id_seq'::regclass)
>  name      | character varying(50) | not null
>  age_range | numrange              | not null
> Indexes:
>     "rangefieldtest_rangetest_pkey" PRIMARY KEY, btree (id)
> }}}
>
> data successfully stored on save (when at least one of the rangefield's 2
> inputs are filled in):
> {{{
>  id | name | age_range
> ----+------+-----------
>   2 |      | [3.0,)
> (1 row)
> }}}

New description:

 The filing of this issue is based on a discussion in IRC (see
 https://botbot.me/freenode/django/2018-08-09/?msg=103129716&page=12 and
 prior messages), followed up by creating a test project to reproduce the
 issue.

 Please do correct me if I am misusing range fields.

 ----

 Saving a modelform with a model's rangefield 2 inputs left empty triggers
 an DB integrity error. I think the culprit lies with `empty_values` not
 containing `['', '']` as a possible empty value. (see the code around
 https://github.com/django/django/blob/1.11.15/django/forms/fields.py#L1026).

 '''`self.compress([])` should return the result of `self.range_type(None,
 None)` instead of just `None`.'''

 With a view like:

 {{{
 def home(request):
     if request.method == 'POST':
         form = RangeTestForm(request.POST)
         if form.is_valid():
             instance = form.save()
     else:
         form = RangeTestForm(request.POST)

     return render(request, 'rangefieldtest/home.html', {'form': form})
 }}}

 Form like:
 {{{
 class RangeTestForm(forms.ModelForm):
     class Meta:
         model = RangeTest
         fields = '__all__'
 }}}

 and Model like:
 {{{
 from django.contrib.postgres.fields import FloatRangeField
 from psycopg2._range import NumericRange

 class RangeTest(models.Model):
     name = models.CharField(max_length=50, blank=True, default='')
     age_range = FloatRangeField(blank=True, default=NumericRange)
 }}}

 I will attach a sample project demonstrating this (use runserver, load the
 home page, click save)


 ----
 psql table definition:
 {{{
                                   Table "public.rangefieldtest_rangetest"
   Column   |         Type          |
 Modifiers
 
-----------+-----------------------+-----------------------------------------------------------------------
  id        | integer               | not null default
 nextval('rangefieldtest_rangetest_id_seq'::regclass)
  name      | character varying(50) | not null
  age_range | numrange              | not null
 Indexes:
     "rangefieldtest_rangetest_pkey" PRIMARY KEY, btree (id)
 }}}

 data successfully stored on save (when at least one of the rangefield's 2
 inputs are filled in):
 {{{
  id | name | age_range
 ----+------+-----------
   2 |      | [3.0,)
 (1 row)
 }}}

 data successfully stored (see id=3 below) on `RangeTest().save()`, which
 should also be the result when saving from the modelform:
 {{{
 test_rangefield=> select * from rangefieldtest_rangetest;
  id | name | age_range
 ----+------+-----------
   2 |      | [3.0,)
   3 |      | (,)
 (2 rows)
 }}}

--

-- 
Ticket URL: <https://code.djangoproject.com/ticket/29656#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 django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/066.8c465091d366be32d5046059ee8bee6a%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to