Locked learning resources

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

Unlock This Lesson

Locked learning resources

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

Unlock This Lesson

Add "shop" Table to Django Admin

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.

Avatar image for Joe Madaus

Joe Madaus on Nov. 4, 2021

Hello again Martin. First, thanks for listening to feedback.

What I mean is a web form with users entering points on a map, those points autofilling a field. Then give the user the ability to input information about them. Kind of like a blog or something. Like a “places I’ve been” sort of thing with user “memories” they can share or not. Then rank those against “other user places” should the user choose to do so. Something like that.

Avatar image for Martin Breuss

Martin Breuss RP Team on Nov. 4, 2021

That’s a great addition to this project @Joe Madaus! 🙌 🗺

For implementing this, you’ll need a way for your users to submit content to your Django back end. Here are a couple of links that might help you piece that functionality together:

You’ll have to pick out the relevant content, but if you go through this process and keep working on it, you’ll definitely learn a lot about Django and you’ll have a cool project to show at the end! :D Let me know if you work it out, I’ll come and record some places there!

Avatar image for Joe Madaus

Joe Madaus on Nov. 4, 2021

Martin

Sounds awesome and thanks for the tips!!! I will definitely let you know when i finish it.

Avatar image for kimstar619

kimstar619 on Aug. 17, 2023

Hello there, When I run makemigrations it says ‘No changes detected’, any ideas? export.json is in the same place as shown in video. I’m on a Mac M1 running Ventura 13.5

thanks, Kim

Avatar image for kimstar619

kimstar619 on Aug. 17, 2023

Nevermind, figured it out, just a stupid mistake....

Avatar image for Rafael Tenorio Gama

Rafael Tenorio Gama on April 24, 2024

I try everything to solve the problem with django.contrib.gis.admin import OSMGeoAdmin but doesn’t work at all!! I have follow all the steps and instructions on gdal.org/download.html but nothing solves too.

We need a update from that lesson on Real Python.

My error is: when run python manage.py runserver

ImportError: cannot import name ‘OSMGeoAdmin’ from ‘django.contrib.gis.admin’.

Avatar image for gabriel

gabriel on May 13, 2024

@Rafael Tenorio Gama I got stuck on the same part but got it to work using the following in my admin.py file. However, i haven’t figured out how to make the list_display option work yet.

from django.contrib import admin
from django.contrib.gis.admin import GISModelAdmin
from .models import Shop

admin.site.register(Shop, GISModelAdmin)

I found this at the very bottom of the following django doc. GeoDjango Tutorial Hope this helps.

Avatar image for jwil

jwil on Sept. 8, 2024

@gabriel and @Rafael Tenorio Gama I was able to get it working with the following in admin.py

from django.contrib.gis import admin
from django.contrib.gis.admin import GISModelAdmin
from .models import Shop

@admin.register(Shop)
class ShopAdmin(GISModelAdmin):
    list_display = ('name', 'location')

Also, I found GISModelAdmin by discovering this: django.readthedocs.io/en/4.2.x/ref/contrib/gis/admin.html#osmgeoadmin

Avatar image for Thierry Gagné

Thierry Gagné on Oct. 2, 2024

Just want to say thanks to gabriel and jwil above me: I had the same problem as them and using GISModelAdmin instead of OSMGeoAdmin solved the issue. It is a shame RealPython does not want to update the Contents tab with these solutions.

Avatar image for Pepe

Pepe on March 26, 2025

I had the same issue, after Django 5.x OSMGeoAdmin doesn’t exists anymore, instead use GISModelAdmin class.

Become a Member to join the conversation.