Opened 18 years ago
Closed 17 years ago
#3982 closed (fixed)
Allow Field subclasses to coerce arbitrary Python types
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Keywords: | coerce coercion | |
Cc: | jm.bugtracking@…, elsdoerfer@… | Triage Stage: | Unreviewed |
Has patch: | yes | Needs documentation: | yes |
Needs tests: | yes | Patch needs improvement: | yes |
Easy pickings: | no | UI/UX: | no |
Description
In working with a recent DurationField patch (#2443), I noticed that Django seems to rely on the backend database driver to coerce data into native Python types. However, when adding new fields with non-standard mappings (such as FloatField for storage, but timedelta as a native type, as in DurationField), to_python
needs to be called explicitly when populating an object from the database in order to be usable. This simple patch does just that, using to_python
to coerce native Python types, after whatever coercion might be done by the database.
Attachments (3)
Change History (11)
by , 18 years ago
Attachment: | to_python.diff added |
---|
by , 18 years ago
Attachment: | coerce.diff added |
---|
Adds support for a coerce
Field method to handle coercion
comment:1 by , 18 years ago
Keywords: | coerce coercion added; to_python removed |
---|---|
Summary: | [patch] Use fields' to_python to coerce Python data types → Allow Field subclasses to coerce arbitrary Python types |
The attached patch allows Field subclasses to define a coerce
method that takes a single value and returns any Python type, that will then be attached to the model instance as the appropriate attribute. This happens after retrieval from the database, manual instantiation of objects, and deserialization.
The one pitfall is that, due to the way bits of Django work, the value sent to coerce
might be:
- a string (if the model came from the DB)
- a native Python type (if it came from a serializer, having already gone through
to_python
) - possibly some other situation I haven't run into yet
So the coerce
method should take these different situations into account.
Here's an example, from DurationField, which will be added to #2443 soon.
def coerce(self, value): return datetime.timedelta(seconds=float(value))
comment:2 by , 18 years ago
Needs documentation: | set |
---|---|
Needs tests: | set |
Patch needs improvement: | set |
I forgot to add all the checkboxes, since there's much more needed to call this done.
comment:3 by , 18 years ago
Cc: | added |
---|
by , 18 years ago
Attachment: | lazy_attribute.diff added |
---|
An attempt at generic lazily-instantiated attributes
comment:4 by , 18 years ago
comment:5 by , 18 years ago
Owner: | changed from | to
---|
There's some issue drift going on here. The last patch has close to nothing to do with the original ticket, which is essentially about helping create Field sub-classes. Lazy instantion is not a requirement there and is an orthogonal issue. Let's try to keep one issue per ticket, please.
I'm going to get around to tidying up the various Field sub-classing ticket this week and I'll close this when that happens. You should open another ticket for the lazy portion after that (probably best to wait until then so that you can write a patch against the code that exists in trunk).
comment:6 by , 18 years ago
Yeah, I admit there is some drift here, but it's mainly because lazy instantiation seems to be a better approach to solve the original problem this ticket was opened for. I'll wait and see the results of your work this week, and if this one needs to just close as an invalid, I'm fine with that.
comment:7 by , 17 years ago
Cc: | added |
---|
Would be nice if this could be fixd at some point. Field subclassing is severely limited currently.
comment:8 by , 17 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Looks like this was fixed with the addition of SubFieldBase and the whole field subclassing stuff.
Path to force
to_python
data type coercion during data retrieval