Skip to content
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

Value conversion on assignment #74

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions geoposition/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,26 @@
from .forms import GeopositionField as GeopositionFormField


class CastOnAssignDescriptor(object):
"""
A property descriptor which ensures that `field.to_python()` is called on _every_ assignment to the field.

This used to be provided by the `django.db.models.subclassing.Creator` class, which in turn
was used by the deprecated-in-Django-1.10 `SubfieldBase` class, hence the reimplementation here.
"""

def __init__(self, field):
self.field = field

def __get__(self, obj, type=None):
if obj is None:
return self
return obj.__dict__[self.field.name]

def __set__(self, obj, value):
obj.__dict__[self.field.name] = self.field.to_python(value)


class GeopositionField(models.Field):
description = _("A geoposition (latitude and longitude)")

Expand Down Expand Up @@ -40,6 +60,10 @@ def to_python(self, value):

return Geoposition(latitude, longitude)

def contribute_to_class(self, cls, name):
super(GeopositionField, self).contribute_to_class(cls, name)
setattr(cls, name, CastOnAssignDescriptor(self))

def from_db_value(self, value, expression, connection, context):
return self.to_python(value)

Expand Down
4 changes: 4 additions & 0 deletions geoposition/tests/test_geoposition.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,7 @@ def test_db_value_to_python_object(self):
obj = PointOfInterest.objects.create(name='Foo', address='some where', city='city', zipcode='12345', position=Geoposition(52.5, 13.4))
poi = PointOfInterest.objects.get(id=obj.id)
self.assertIsInstance(poi.position, Geoposition)

def test_value_conversion_on_assignment(self):
obj = PointOfInterest(name='Foo', address='some where', city='city', zipcode='12345', position='52.5,13.4')
self.assertEqual(obj.position, Geoposition(52.5, 13.4))