[Django] #24170: DateTimeRangeField: widget doesn't implement decompress()

110 views
Skip to first unread message

Django

unread,
Jan 17, 2015, 3:36:24 PM1/17/15
to django-...@googlegroups.com
#24170: DateTimeRangeField: widget doesn't implement decompress()
-------------------------------------+-------------------------------------
Reporter: joelburton | Owner: nobody
Type: Uncategorized | Status: new
Component: Database layer | Version: 1.8alpha1
(models, ORM) | Keywords: DateTimeRangeField
Severity: Normal | decompress
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
1. Create a model with a DateTimeRangeField and another field (I used just
one other, a SlugField)

2. Via the admin, add a record with a valid slug and datetimerange

3. Try to edit the record, changing the slug

(This was done with a Postgres backend)

This traceback is produced:

{{{
Environment:


Request Method: POST
Request URL: http://localhost:8000/admin/homework/homework/3/

Django Version: 1.8a1
Python Version: 3.4.2
Installed Applications:
('django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.postgres',
'homework')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware')


Traceback:
File "/Users/joel/programming/django18play/venv/lib/python3.4/site-
packages/django/core/handlers/base.py" in get_response
131. response = wrapped_callback(request,
*callback_args, **callback_kwargs)
File "/Users/joel/programming/django18play/venv/lib/python3.4/site-
packages/django/contrib/admin/options.py" in wrapper
615. return self.admin_site.admin_view(view)(*args,
**kwargs)
File "/Users/joel/programming/django18play/venv/lib/python3.4/site-
packages/django/utils/decorators.py" in _wrapped_view
110. response = view_func(request, *args, **kwargs)
File "/Users/joel/programming/django18play/venv/lib/python3.4/site-
packages/django/views/decorators/cache.py" in _wrapped_view_func
54. response = view_func(request, *args, **kwargs)
File "/Users/joel/programming/django18play/venv/lib/python3.4/site-
packages/django/contrib/admin/sites.py" in inner
226. return view(request, *args, **kwargs)
File "/Users/joel/programming/django18play/venv/lib/python3.4/site-
packages/django/contrib/admin/options.py" in change_view
1518. return self.changeform_view(request, object_id, form_url,
extra_context)
File "/Users/joel/programming/django18play/venv/lib/python3.4/site-
packages/django/utils/decorators.py" in _wrapper
34. return bound_func(*args, **kwargs)
File "/Users/joel/programming/django18play/venv/lib/python3.4/site-
packages/django/utils/decorators.py" in _wrapped_view
110. response = view_func(request, *args, **kwargs)
File "/Users/joel/programming/django18play/venv/lib/python3.4/site-
packages/django/utils/decorators.py" in bound_func
30. return func.__get__(self, type(self))(*args2,
**kwargs2)
File
"/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/contextlib.py"
in inner
30. return func(*args, **kwds)
File "/Users/joel/programming/django18play/venv/lib/python3.4/site-
packages/django/contrib/admin/options.py" in changeform_view
1472. change_message =
self.construct_change_message(request, form, formsets)
File "/Users/joel/programming/django18play/venv/lib/python3.4/site-
packages/django/contrib/admin/options.py" in construct_change_message
1020. if form.changed_data:
File "/Users/joel/programming/django18play/venv/lib/python3.4/site-
packages/django/forms/forms.py" in changed_data
466. if field.has_changed(initial_value, data_value):
File "/Users/joel/programming/django18play/venv/lib/python3.4/site-
packages/django/forms/fields.py" in has_changed
1126. initial = self.widget.decompress(initial)
File "/Users/joel/programming/django18play/venv/lib/python3.4/site-
packages/django/forms/widgets.py" in decompress
850. raise NotImplementedError('Subclasses must implement this
method.')

Exception Type: NotImplementedError at /admin/homework/homework/3/
Exception Value: Subclasses must implement this method.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/24170>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Jan 17, 2015, 7:25:37 PM1/17/15
to django-...@googlegroups.com
#24170: DateTimeRangeField: widget doesn't implement decompress()
-------------------------------------+-------------------------------------
Reporter: joelburton | Owner: ngzhian
Type: Uncategorized | Status: assigned

Component: Database layer | Version: 1.8alpha1
(models, ORM) |
Severity: Normal | Resolution:
Keywords: DateTimeRangeField | Triage Stage:
decompress | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by ngzhian):

* owner: nobody => ngzhian
* needs_better_patch: => 0
* status: new => assigned
* needs_tests: => 0
* needs_docs: => 0


--
Ticket URL: <https://code.djangoproject.com/ticket/24170#comment:1>

Django

unread,
Jan 17, 2015, 8:53:31 PM1/17/15
to django-...@googlegroups.com
#24170: DateTimeRangeField: widget doesn't implement decompress()
-------------------------------------+-------------------------------------
Reporter: joelburton | Owner: ngzhian
Type: Uncategorized | Status: assigned
Component: Database layer | Version: 1.8alpha1
(models, ORM) |
Severity: Normal | Resolution:
Keywords: DateTimeRangeField | Triage Stage:
decompress | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by ngzhian):

Error is caused because all the new fields added in 1.8
`IntegerRangeField`, `FloatRangeField`, `DateTimeRangeField`, and
`DateRangeField`, all inherit from `BaseRangeField`.

`BaseRangeField` itself defines its widget as
`forms.MultiWidget([self.base_field.widget, self.base_field.widget])`
[https://github.com/django/django/blob/master/django/contrib/postgres/forms/ranges.py#L18
postgres.forms.ranges.py#18]. However, `MultiWidget` raises `
NotImplementedError('Subclasses must implement this method.')` just like
@joelburton mentioned.

I'm not sure how to patch this. Thinking that:
1. Each of the child classes of `BaseRangeField` should overwrite
`__init__` to put in their own widgets.
2. create a new `widgets.py` file in `contrib.postgres` to define the new
widgets.

Comments?

--
Ticket URL: <https://code.djangoproject.com/ticket/24170#comment:2>

Django

unread,
Jan 18, 2015, 4:01:32 PM1/18/15
to django-...@googlegroups.com
#24170: DateTimeRangeField: widget doesn't implement decompress()
-------------------------------------+-------------------------------------
Reporter: joelburton | Owner: ngzhian
Type: Uncategorized | Status: assigned
Component: Database layer | Version: 1.8alpha1
(models, ORM) |
Severity: Normal | Resolution:
Keywords: DateTimeRangeField | Triage Stage: Accepted
decompress |

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by charettes):

* stage: Unreviewed => Accepted


Comment:

I think creating a single `RangeWidget(widgets.Widget)` class in a new
`widgets` module that implements the decompress method should do.

{{{#!python
# django/contrib/postgres/widgets.py

class RangeWidget(widgets.Widget):
def __init__(base_widget, attrs=None):
widgets = (base_widget, base_widget)
super(RangeWidget, self).__init__(widgets, attrs=attrs)

def decompress(self, value):
if value:
return (value.lower, value.upper)
return (None, None)
}}}


Please make a
[https://docs.djangoproject.com/en/dev/internals/contributing/writing-code
/working-with-git/#publishing-work PR] of your patch to make review
easier. Thanks!

--
Ticket URL: <https://code.djangoproject.com/ticket/24170#comment:3>

Django

unread,
Jan 18, 2015, 7:18:28 PM1/18/15
to django-...@googlegroups.com
#24170: DateTimeRangeField: widget doesn't implement decompress()
-------------------------------------+-------------------------------------
Reporter: joelburton | Owner: ngzhian
Type: Uncategorized | Status: assigned
Component: Database layer | Version: 1.8alpha1
(models, ORM) |
Severity: Normal | Resolution:
Keywords: DateTimeRangeField | Triage Stage: Accepted
decompress |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by ngzhian):

Replying to [comment:3 charettes]:


> I think creating a single `RangeWidget(widgets.Widget)` class in a new
`widgets` module that implements the decompress method should do.

Implemented it and submitted a PR, it's lacking test though, I'm not too
sure how to test it. Will creating a field of each type


`IntegerRangeField`, `FloatRangeField`, `DateTimeRangeField`, and

`DateRangeField` and asserting `self.widget.decompress()` be sufficient?

--
Ticket URL: <https://code.djangoproject.com/ticket/24170#comment:4>

Django

unread,
Jan 18, 2015, 8:55:34 PM1/18/15
to django-...@googlegroups.com
#24170: DateTimeRangeField: widget doesn't implement decompress()
-------------------------------------+-------------------------------------
Reporter: joelburton | Owner: ngzhian
Type: | Status: assigned
Cleanup/optimization |

Component: Database layer | Version: 1.8alpha1
(models, ORM) |
Severity: Normal | Resolution:
Keywords: DateTimeRangeField | Triage Stage: Accepted
decompress |
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by MarkusH):

* needs_docs: 0 => 1
* has_patch: 0 => 1
* type: Uncategorized => Cleanup/optimization
* needs_tests: 0 => 1


Comment:

Replying to [comment:4 ngzhian]:


> Implemented it and submitted a PR, it's lacking test though, I'm not too
sure how to test it. Will creating a field of each type
`IntegerRangeField`, `FloatRangeField`, `DateTimeRangeField`, and
`DateRangeField` and asserting `self.widget.decompress()` be sufficient?

I'd have a look at the tests of the "normal" widgets if there aren't any
tests yet. I don't think there is a need to tests all range fields.

--
Ticket URL: <https://code.djangoproject.com/ticket/24170#comment:5>

Django

unread,
Jan 22, 2015, 5:17:54 AM1/22/15
to django-...@googlegroups.com
#24170: DateTimeRangeField: widget doesn't implement decompress()
-------------------------------------+-------------------------------------
Reporter: joelburton | Owner: ngzhian
Type: | Status: assigned
Cleanup/optimization |
Component: Database layer | Version: 1.8alpha1
(models, ORM) |
Severity: Normal | Resolution:
Keywords: DateTimeRangeField | Triage Stage: Ready for
decompress | checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by MarkusH):

* needs_docs: 1 => 0
* needs_tests: 1 => 0
* stage: Accepted => Ready for checkin


--
Ticket URL: <https://code.djangoproject.com/ticket/24170#comment:6>

Django

unread,
Jan 22, 2015, 2:51:06 PM1/22/15
to django-...@googlegroups.com
#24170: DateTimeRangeField: widget doesn't implement decompress()
-------------------------------------+-------------------------------------
Reporter: joelburton | Owner: ngzhian
Type: | Status: closed
Cleanup/optimization |

Component: Database layer | Version: 1.8alpha1
(models, ORM) |
Severity: Normal | Resolution: fixed

Keywords: DateTimeRangeField | Triage Stage: Ready for
decompress | checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Ng Zhi An <ngzhian@…>):

* status: assigned => closed
* resolution: => fixed


Comment:

In [changeset:"4669b6a807811d6763b9fdc5df974cb67aa1fb56"]:
{{{
#!CommitTicketReference repository=""
revision="4669b6a807811d6763b9fdc5df974cb67aa1fb56"
Fixed #24170 -- Implemented decompress for BaseRangeField widgets
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/24170#comment:7>

Django

unread,
Jan 23, 2015, 3:09:36 PM1/23/15
to django-...@googlegroups.com
#24170: DateTimeRangeField: widget doesn't implement decompress()
-------------------------------------+-------------------------------------
Reporter: joelburton | Owner: ngzhian
Type: | Status: closed
Cleanup/optimization |
Component: Database layer | Version: 1.8alpha1
(models, ORM) |
Severity: Normal | Resolution: fixed
Keywords: DateTimeRangeField | Triage Stage: Ready for
decompress | checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Tim Graham <timograham@…>):

In [changeset:"56015c01c4725aeeb225a62f2702a4bbb3a3ce54"]:
{{{
#!CommitTicketReference repository=""
revision="56015c01c4725aeeb225a62f2702a4bbb3a3ce54"
[1.8.x] Fixed #24170 -- Implemented decompress for BaseRangeField widgets

Backport of 4669b6a807811d6763b9fdc5df974cb67aa1fb56 from master
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/24170#comment:8>

Reply all
Reply to author
Forward
0 new messages