Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set the default subtitles language in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue.

Add "shop" Table to Django Admin

Give Feedback

In this video we will add our shop database table to our admin view and load some initial records.

At this point you should have most of your app set up along with a superuser account for Django authentication.

What you will do now is register your shop model in the Admin interface. To do so you will subclass a GeoDjango class called OSMGeoAdmin and specifying the list of columns to display for the view.

00:00 Welcome to video number nine in our series on creating a location-based web app with Django and GeoDjango. In this video, we will add our shop database table to our admin view and load some initial records. At this point, you should have most of your app set up, along with a superuser account for Django authentication.

00:21 What you will do now is register your shop model in the admin interface. To do so, you will subclass a GeoDjango class by the name of OSMGeoAdmin, and specify the list of columns to display for the view.

00:37 Back in our editor, you’re going to modify a different file this time—admin.py, located in the app part of your project. This file provides a way for you to customize the built-in admin pages.

00:49 Add the following code to this file.

00:56 If your site is still running, stop it by pressing Control + C at the terminal. Then relaunch your site with the manage.py runserver command.

01:06 Go back into your site and then go to the admin view by typing /admin after the URL in your address bar. You see a new link called Shops.

01:15 Django even capitalized the table name and made it plural for consistency. Let’s look inside. Not surprisingly, we have no shop data yet, but as you can see, the interface has provided a way for us to manually add records if we wanted.

01:29 Instead of doing that by hand, though, you’re going to load your database with some initial data courtesy of the overpass-turbo.eu website. Open this address in your browser.

01:43 Use the Wizard option on this site and type the following query: shop in Baltimore. Build and run the query.

01:59 Once the query completes, choose the Export option at the top of the page, and then click the download link next to raw OSM data.

02:08 This downloads a file to your downloads area called export.json. We want to place export.json in the root of your project—at the same level as the manage.py utility.

02:19 You can take a look inside the file if you’re curious about its structure. But what we’re going to do next is create a Django migration to move this data into our database. To do that, we’re going to execute a manage.py command to initialize an empty migration for our nearbyshops app.

02:37 First, we’ll stop our site by pressing Control + C, and then clean up our view a little. Notice the migrations/ folder falls within the app part of our project, within the nearby shops/ folder. If you expand this, you’ll see artifacts from our previous migration.

02:56 Open your terminal window now and proceed with the --empty migration command.

03:07 If you refresh your migrations/ folder now, you’ll see an empty migration file has been created. You are going to make significant changes to this file.

03:16 You’ll need to add three import statements for some functionality you’ll need. Next, you’ll create a variable to hold the name of your JSON file.

03:28 Then—and this is the lengthy part—you’ll need to complete the code for the following load_data() function. The important parts to note here in the function is the name of your app, 'nearbyshops', and the model name that will be needed, 'Shop'.

03:47 We have one more change to make in the Migration class. Add the load_data function to the operations list.

03:58 Our migration is ready to go. We just have the final step now of running the manage.py migrate command.

04:07 Everything looks good! Let’s relaunch our site and see if we see any shops.

04:20 We’ll go back into the admin view and click the Shops link.

04:26 Great job! You should now see your initial location data. Before we leave this admin view, let’s take a look at what the ADD SHOP button does for us.

04:39 Neat! The OSMGeoAdmin class includes a map view—even though the location is a little off. You should be very pleased with how much you’ve accomplished so far.

04:49 We’re on the home stretch! To wrap up this project, we’re finally going to show our user which shops are nearby—in our next video.

abairy on June 4, 2019

Hello When I try to migrate the data exported from overpass its giving me this error

File “C:\Users\13154\Anaconda3\lib\encodings\cp1252.py”, line 23, in decode return codecs.charmap_decode(input,self.errors,decoding_table)[0] UnicodeDecodeError: ‘charmap’ codec can’t decode byte 0x9d in position 26427: character maps to <undefined>

snandw on June 22, 2019

please help I am getting the same error on a windows machine ,a quick reply would be appreciated i need to submit this as a project

Jackie Wilson RP Team on June 24, 2019

I am traveling with limited access. Do you mean to say your map data (location data in JSON) is causing the error?

drewewhite1 on Feb. 9, 2020

@abairy and @snandw, you may have solved your problem already. If not or for anyone who runs into this issue in the future, I was able to resolve the issue by specifying the encoding upon opening the file. So it looks something like this.

...

with open(str(jsonfile), encoding = "utf8") as datafile:
        objects = json.load(datafile)
        for obj....

Hope this helps!

Amr on Feb. 17, 2020

how to to use file.xlsx instead of file.json? and also how to add any type of file.

Mydhe on April 7, 2020

Just to add, the edit is done in your empty migration file for example mine is named 0002_auto_20200408_0157.py The edit is in this block;

with open(str**(jsonfile), encoding = "utf8") as **datafile:
    objects = json.load(datafile)
    for obj in objects['elements']:
        try:
            objType = obj['type']
            if objType == 'node':
                tags = obj['tags']
                name = tags.get('name','no-name')
                longitude = obj.get('lon', 0)
                latitude = obj.get('lat', 0)
                location = fromstr(f'POINT({longitude} {latitude})', srid=4326)
                Shop(name=name, location = location).save()
        except KeyError:
            pass

Thanks drewewhite1 for the pointer!

jacob6 on May 4, 2020

My Shops table is still empty…no error messages. This is my code:

# Generated by Django 3.0.5 on 2020-05-04 08:55

from django.db import migrations
import json
from django.contrib.gis.geos import fromstr
from pathlib import Path

DATA_FILENAME = 'export.json'

def load_data(apps, schema_editor):
    Shop = apps.get_model('nearbyshops', 'Shop')
    jsonfile = Path(__file__).parents[2] / DATA_FILENAME

    with open(str(jsonfile)) as datafile:
        objects = json.load(datafile)
        for obj in objects['elements']:
            try:
                objType = obj['type']
                if objType == 'node':
                    tags = obj['tags']
                    name = tags.get('name', 'no-name')
                    longitude = obj.get('lon', 0)
                    latitude = obj.get('lat', 0)
                    location = fromstr(
                        f'POINT({longitude} {latitude})', srid=4326
                    )
                    Shop(name=name, location=location).save()
            except KeyError:
                pass

class Migration(migrations.Migration):

    dependencies = [
        ('nearbyshops', '0001_initial'),
    ]

    operations = [
        migrations.RunPython(load_data)
    ]

jacob6 on May 5, 2020

I’ve been over my code a few times now. I’m now getting the following error message:

TypeError: Shop() got an unexpected keyword argument 'location'

My code is as follows:

# Generated by Django 3.0.5 on 2020-05-04 10:00

from django.db import migrations
import json
from django.contrib.gis.geos import fromstr
from pathlib import Path

DATA_FILENAME = 'export.json'

def load_data(apps, schema_editor):
    Shop = apps.get_model('nearbyshops', 'Shop')
    jsonfile = Path(__file__).parents[2] / DATA_FILENAME

    with open(str(jsonfile)) as datafile:
        objects = json.load(datafile)
        for obj in objects['elements']:
            try:
                objType = obj['type']
                if objType == 'node':
                    tags = obj['tags']
                    name = tags.get('name', 'no-name')
                    longitude = obj.get('lon', 0)
                    latitude = obj.get('lat', 0)
                    location = fromstr(
                        f'POINT({longitude} {latitude})', srid=4326
                    )
                    Shop(name=name, location=location).save()
            except KeyError:
                pass

class Migration(migrations.Migration):

    dependencies = [
        ('nearbyshops', '0001_initial'),
    ]

    operations = [
        migrations.RunPython(load_data)
    ]

As per the instructions in the video the export.json is on the same level as manage.py. I’ve been over this code a lot of times now, and I’ve tried googling, with no success…can anyone help out?

pmannion95 on July 23, 2020

Hi, I’m running into an odd error that I believe is related the map data but I’ve follow the instructions in the video for querying shops in Baltimore and downloading as raw OSM data.

django.contrib.gis.geos.error.GEOSException: Error encountered checking Geometry returned from GEOS C function "GEOSWKTReader_read_r".

My migration code is below, but otherwise I’m unsure of what may be the issue. I’ve retraced it, and redownloaded the export.json data to no avail.

My code is below: ``` # Generated by Django 3.0.8 on 2020-07-21 05:08

from django.db import migrations import json from django.contrib.gis.geos import fromstr from pathlib import Path

DATA_FILENAME = ‘export.json’

def load_data(apps, schema_editor): Shop = apps.get_model(‘nearbyshops’, ‘Shop’) jsonfile = Path(file).parents[2] / DATA_FILENAME

with open(str(jsonfile)) as datafile:
    objects = json.load(datafile)

    for obj in objects['elements']:
        try:
            objType = obj['type']
            if objType == 'node':
                tags = obj['tags']
                name = tags.get('name', 'no-name')
                longitude = obj.get('lon', 0)
                latitude = obj.get('lat', 0)
                location = fromstr(f'POINT({longitude} {latitude}', srid=4326)

                Shop(name=name, location=location).save()
        except KeyError:
            pass

class Migration(migrations.Migration):

dependencies = [
    ('nearbyshops', '0001_initial'),
]

operations = [
    migrations.RunPython(load_data)
]

```

karakus on Sept. 19, 2020

FYI - After spending some ‘extended happy time’ googling and checking my installs and code, I discovered that attempting to view the location in /Admin using OSMGeoAdmin doesn’t display the map correctly if using Safari, but works using Chrome. Hope this helps others!

See FAQ here for the source of my new found wisdom.

Enjoying the style and pace of the Tutorial all the same!

Become a Member to join the conversation.