Python Forum
How to auto fill latitude and longitude fields in Django2.0.6? - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: Web Scraping & Web Development (https://python-forum.io/forum-13.html)
+--- Thread: How to auto fill latitude and longitude fields in Django2.0.6? (/thread-11037.html)



How to auto fill latitude and longitude fields in Django2.0.6? - PrateekG - Jun-19-2018

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!


RE: How to auto fill latitude and longitude fields in Django2.0.6? - gontajones - Jun-19-2018

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.


RE: How to auto fill latitude and longitude fields in Django2.0.6? - PrateekG - Jun-20-2018

(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>


RE: How to auto fill latitude and longitude fields in Django2.0.6? - gontajones - Jun-20-2018

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



RE: How to auto fill latitude and longitude fields in Django2.0.6? - PrateekG - Jun-20-2018

(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.


RE: How to auto fill latitude and longitude fields in Django2.0.6? - gontajones - Jun-20-2018

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.


RE: How to auto fill latitude and longitude fields in Django2.0.6? - PrateekG - Jun-21-2018

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?


RE: How to auto fill latitude and longitude fields in Django2.0.6? - gontajones - Jun-21-2018

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?


RE: How to auto fill latitude and longitude fields in Django2.0.6? - PrateekG - Jun-21-2018

(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?


RE: How to auto fill latitude and longitude fields in Django2.0.6? - gontajones - Jun-21-2018

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()