Python Forum

Full Version: How to auto fill latitude and longitude fields in Django2.0.6?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi Experts,

I have created an address form in Django2.0.6+Mysql+Python3.6 and it has location,address,latitude,longitude fields.

I want to auto filled the latitude and longitude fields once user entered the address.

For this purpose I have written following code-

In models.py-
from location_field.models.plain import PlainLocationField
class Store(models.Model):
    location = PlainLocationField(based_fields=['address'], zoom=7, null=True)
    @property
    def latitude(self):
        latitiude, _ = self.location.split(',')
        return latitiude

    @property
    def longitude(self):
        _, longitude = self.location.split(',')
        return longitude
in admin.py-
class StoreAdmin(admin.ModelAdmin):
    list_display = ('id', 'chain', 'name', 'building', 'description', 'postal_code', 'address', 'phone',
                'latitude', 'longitude', 'opening_hours')
    readonly_fields = ('latitude', 'longitude',)
But when I open my address form I am getting following error in browser-
Error:
Exception Type: ValueError Exception Value: not enough values to unpack (expected 2, got 1) Exception Location: E:\mycms\models.py in latitude, line 230
The complete server log is as below-
Error:
Internal Server Error: /mycms/store/ Traceback (most recent call last): File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\db\models\options.py", line 566, in get_field return self.fields_map[field_name] KeyError: 'latitude' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\contrib\admin\utils.py", line 276, in lookup_field f = _get_non_gfk_field(opts, name) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\contrib\admin\utils.py", line 307, in _get_non_gfk_field field = opts.get_field(name) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\db\models\options.py", line 568, in get_field raise FieldDoesNotExist("%s has no field named '%s'" % (self.object_name, field_name)) django.core.exceptions.FieldDoesNotExist: Store has no field named 'latitude' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\core\handlers\exception.py", line 35, in inner response = get_response(request) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\core\handlers\base.py", line 158, in _get_response response = self.process_exception_by_middleware(e, request) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\core\handlers\base.py", line 156, in _get_response response = response.render() File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\template\response.py", line 106, in render self.content = self.rendered_content File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\template\response.py", line 83, in rendered_content content = template.render(context, self._request) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\template\backends\django.py", line 61, in render return self.template.render(context) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\template\base.py", line 175, in render return self._render(context) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\template\base.py", line 167, in _render return self.nodelist.render(context) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\template\base.py", line 943, in render bit = node.render_annotated(context) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\template\base.py", line 910, in render_annotated return self.render(context) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\template\loader_tags.py", line 155, in render return compiled_parent._render(context) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\template\base.py", line 167, in _render return self.nodelist.render(context) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\template\base.py", line 943, in render bit = node.render_annotated(context) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\template\base.py", line 910, in render_annotated return self.render(context) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\template\loader_tags.py", line 155, in render return compiled_parent._render(context) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\template\base.py", line 167, in _render return self.nodelist.render(context) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\template\base.py", line 943, in render bit = node.render_annotated(context) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\template\base.py", line 910, in render_annotated return self.render(context) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\template\loader_tags.py", line 67, in render result = block.nodelist.render(context) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\template\base.py", line 943, in render bit = node.render_annotated(context) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\template\base.py", line 910, in render_annotated return self.render(context) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\template\loader_tags.py", line 67, in render result = block.nodelist.render(context) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\template\base.py", line 943, in render bit = node.render_annotated(context) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\template\base.py", line 910, in render_annotated return self.render(context) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\template\library.py", line 214, in render _dict = self.func(*resolved_args, **resolved_kwargs) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\contrib\admin\templatetags\admin_list.py", line 326, in result_list 'results': list(results(cl))} File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\contrib\admin\templatetags\admin_list.py", line 302, in results yield ResultList(None, items_for_result(cl, res, None)) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\contrib\admin\templatetags\admin_list.py", line 293, in __init__ super().__init__(*items) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\contrib\admin\templatetags\admin_list.py", line 212, in items_for_result f, attr, value = lookup_field(field_name, result, cl.model_admin) File "C:\Users\hitman\AppData\Local\Continuum\anaconda3\lib\site-packages\django\contrib\admin\utils.py", line 287, in lookup_field attr = getattr(obj, name) File "E:\mycms\models.py", line 214, in latitude latitiude, _ = self.location.split(',') ValueError: not enough values to unpack (expected 2, got 1)
Please someone help me to solve the issue!
You have to check what is the content of the location field (variable).
The split() method is just returning 1 item but your code expects 2.
latitiude, _ = self.location.split(',')
And I just saw that your wrote latitude wrong.
(Jun-19-2018, 11:14 PM)gontajones Wrote: [ -> ]You have to check what is the content of the location field (variable).
The split() method is just returning 1 item but your code expects 2.
latitiude, _ = self.location.split(',')
And I just saw that your wrote latitude wrong.

Thanks, it was a silly mistake, I corrected the spelling of latitude.
Currently I am giving a default value to the address field as below-
class Store(OwnedModel):
    building = models.ForeignKey(Building, related_name='building', on_delete=models.SET_NULL, blank=True, null=True)
    postal_code = models.CharField(max_length=6)
    address = models.TextField(default='Singapore')
    location = PlainLocationField(based_fields=['address'], zoom=7, null=True)
But the error is same. Should I need to store a default value of location in db also?

For testing I added location value for a store in DB and restarted the server but the error is same again.

I added a print statement after location variable in models.py and restarted the server; in server log I got:
location:: <location_field.models.plain.PlainLocationField>
location:: <location_field.models.plain.PlainLocationField>
With "null=True" you allow empty values.
So, test its content before the split:
from location_field.models.plain import PlainLocationField
class Store(OwnedModel):
    building = models.ForeignKey(Building, related_name='building', on_delete=models.SET_NULL, blank=True, null=True)
    postal_code = models.CharField(max_length=6)
    address = models.TextField(default='Singapore')
    location = PlainLocationField(based_fields=['address'], zoom=7, null=True)

    @property
    def get_lat_log(self):
        latitude = ''
        longitude = ''
        try:
            print('Location: ' + str(self.location)) # DEBUG
            latitude, longitude = self.location.split(',')
        except Exception as e:
            print('Exception: ' + str(e))
        return latitude,longitude

    def __str__(self):
		return self.location
(Jun-20-2018, 10:08 AM)gontajones Wrote: [ -> ]With "null=True" you allow empty values.
So, test its content before the split:
from location_field.models.plain import PlainLocationField
class Store(OwnedModel):
    building = models.ForeignKey(Building, related_name='building', on_delete=models.SET_NULL, blank=True, null=True)
    postal_code = models.CharField(max_length=6)
    address = models.TextField(default='Singapore')
    location = PlainLocationField(based_fields=['address'], zoom=7, null=True)

    @property
    def get_lat_log(self):
        latitude = ''
        longitude = ''
        try:
            print('Location: ' + str(self.location)) # DEBUG
            latitude, longitude = self.location.split(',')
        except Exception as e:
            print('Exception: ' + str(e))
        return latitude,longitude

    def __str__(self):
		return self.location

Thanks! I have put try-except in my code and able to see following print messages in logs-
Location: 8 SHENTON WAY #43-01 AXA TOWER Singapore
Exception: not enough values to unpack (expected 2, got 1)

Same I did for longitude function but no any message was printed; it means longitude field is missing here.

It seems 'PlainLocationField' is not working properly here.
So your location variable has no ',' in its content:

Location: 8 SHENTON WAY #43-01 AXA TOWER Singapore
This content will return only 1 item, when you call split(','), but your code expects 2.
So what do you think how to modify my code so that no need to add a extra column- 'location' in my database and latitude/longitude fields fill when user entered the address?
I'll install this Django app to see how it works.

What is the content of location field when you try to add a new Place from the admin/ site?
(Jun-21-2018, 10:04 AM)gontajones Wrote: [ -> ]I'll install this Django app to see how it works.

What is the content of location field when you try to add a new Place from the admin/ site?

I am able to make it works. There was some db data issue. My update code is as below-
models.py:
class Store(models.Model):
    postal_code = models.CharField(max_length=6)
    address = models.TextField()
    location = PlainLocationField(based_fields=['address'], zoom=7, null=True)
    phone = models.CharField(max_length=60, blank=True, null=True)
    latitude = models.FloatField()
    longitude = models.FloatField()
    class Meta:
        managed = False
        db_table = 'store'
admin.py:
class StoreAdmin(admin.ModelAdmin):
list_display = ('postal_code', 'address','phone', 'latitude', 'longitude')

So once user entered the address, location is auto filled with the values of latitude,longitude.

Since I have separate fields for storing latitude/longitude; I want to fetch their values from the location field and put them in respective fields.
How can I do that with some Python function?
Where in your code are you writing the input in the DB?
Before the method save(), you should split location:
myModel = form.Place()
location = myModel.cleaned_data['location']
latitude,longitude = [float(x) for x in location.split(',')]
myModel.save()