django-geoposition icon indicating copy to clipboard operation
django-geoposition copied to clipboard

Geoposition Field save manually

Open Alejoss opened this issue 7 years ago • 5 comments

I need to save a Geoposition Field manually. How can I do that?

class Address(models.Model):
    position = GeopositionField(null=True, db_index=True)

>>>  x.position = {'lat': 52.5, 'lng': 13.4}
>>>  x.save()
>>> x.position.latitude
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'latitude'
>>> x.id
1
y = Address.objects.get(id=1)
InvalidOperation: Invalid literal for Decimal: u"{'lat': 52.5"

If you believe this is a bug, as I suspect. I could solve it and collaborate with the library.

Alejoss avatar Oct 26 '16 21:10 Alejoss

I took the {'lat': 52.5, 'lng': 13.4} from the docs.

... I believe the bug is in the GeopositionField, in the to_python() function:

def to_python(self, value):
    if not value or value == 'None':
        return None
    if isinstance(value, Geoposition):
        return value
    if isinstance(value, list):
        return Geoposition(value[0], value[1])

    # ! It could be a dict (if the user sets the values manually like this: {'lat': 52.5, 'lng': 13.4})

    # default case is string  <--- This is not correct. 
    value_parts = value.rsplit(',')
    try:
        latitude = value_parts[0]
    except IndexError:
        latitude = '0.0'
    try:
        longitude = value_parts[1]
    except IndexError:
        longitude = '0.0'

Alejoss avatar Oct 26 '16 22:10 Alejoss

Hello,

After applicating your change to my version of geoposition i was still left with one trouble which was that lat and long would always be 0.

This is due to the fact value_parts.rsplit('s') ended up in ["[Decimal('50.8330962')", " Decimal('4.358464599999934')]"], making the conversion raise an exception. Changing the code to remove litterals from the string made everything go fine. wonder if it helps. But thanks anyway

MaxLarue avatar Apr 07 '17 09:04 MaxLarue

Changing

....
        value_parts = value.rsplit(',')
....

to

....
       value_parts = eval(value)
       if isinstance(value_parts,dict):
            value_parts=(value_parts['lat'],value_parts['lng'])
....

worked nicely for me.

ghost avatar Aug 24 '17 08:08 ghost

Hi. I am unable to save the instace. Could you please explain a bit in detail then I can workaround on this issue.

elcolie avatar Nov 06 '17 05:11 elcolie

Okay. Just for now. This is my workaround on the https://github.com/philippbosch/django-geoposition/archive/django-1.11.zip

models.py

class AbstractAddress(models.Model):
    ...
    position = GeopositionField()
comp.position = "23.2,122.0"
comp.save()

The position has to be string concatenate with string.

elcolie avatar Nov 06 '17 05:11 elcolie