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

ValidationError ['Invalid input for a Location instance. Latitude must be convertible to float '] #15

Closed
sajib1066 opened this issue Jul 3, 2020 · 7 comments

Comments

@sajib1066
Copy link

when I goto my location list after create location then found this error.
err
please solve it urgently.

@edgaru
Copy link
Contributor

edgaru commented Jul 3, 2020

Hello, what value is saved in the database?

@edgaru
Copy link
Contributor

edgaru commented Jul 3, 2020

It will be beacuse the value (as string) is converte to string accesing like a list ("{},{}".format(value[0], value[1])) and save to the database.

For example if I add it to a migrate with default value.

migrations.AddField(
            model_name='order',
            name='destination_location',
            field=mapbox_location_field.models.LocationField(default='0,0', map_attrs={}),
            preserve_default=False,
)

All updated fields will have '0,' as value in the database.

If I implement for example django-rest-framework with LocationField I have the same result.

I solved temporaly adding "or isinstance(value, str)" to the LocationField model.

   def get_prep_value(self, value):
       if value is None or isinstance(value, str):
           return value

       return "{},{}".format(value[0], value[1])

@simon-the-shark
Copy link
Owner

simon-the-shark commented Jul 3, 2020

Yeah, this error probably occurs when the value from db is converted to Python representation. However, I raise it purposely when parsing is impossible. It means you have some wrong value stored in db.
The big question is WHY?
I always remain open to the possibility that it's a bug in saving the value, but I haven't encountered anything similar, so I need some information about your configuration, to reproduce this problem.
Do you use plain or spatial field? Is it nullable? Read-only? Anything that you think may be useful. Maybe some code example for easier bug reproducing? That would be great too.
Did you have something saved in your database before implementing this field? You can try to clean your db and then check if you still encounter this problem on fresh new db.

@edgaru
Copy link
Contributor

edgaru commented Jul 3, 2020

django-rest-framework take the field like charfield and if you send it like a string it save only de two first chars. For example if I send "12.23,11.40" save like "1,2" in the database.

@simon-the-shark
Copy link
Owner

I haven't used my package with DRF, but something seems definitely wrong, so I will take a closer look at it today.

@simon-the-shark
Copy link
Owner

Ok, so basically I changed get_prop_value function because it used to assume that you always provide a tuple or list and not a string value. Of course, DRF's serialization with CharField is a clear example, why it was a wrong assumption. Since 1.6.1 it's fixed. However, saving string values is not a safe procedure and can potentially cause multiple errors (similar to @sajib1066 ). That's why I implemented the protection mechanism and when string can't be parsed, the default value of null (in case of nullable field) or "0,0" (in case of non-nullable field) is saved to db. If it's undesired behavior, then you have to implement a validation mechanism in your API. It's quite simple. That's a code example:

from rest_framework import serializers
from mapbox_location_field.forms import parse_location, ValidationError

class LocationSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = SomeLocationModel
        fields = ["location"]

    def validate_location(self, value):
        try:
            parse_location(value)
        except ValidationError as error:
            raise serializers.ValidationError(error.message)
        return value

It's serializer for SomeLocationModel with location field, which is a LocationField

@simon-the-shark
Copy link
Owner

I hope I resolved this issue. If you still encounter it, reopen it, or create a new one. If you have some wrong values stored in db, you have to clean it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants