Создание веб-приложения на основе местоположения с помощью Django и GeoDjango

Оглавление

В этом уроке вы узнаете, как использовать Django и GeoDjango для создания веб-приложения на основе местоположения с нуля. Вам предстоит создать простое приложение "Близлежащие магазины", в котором будут перечислены магазины, расположенные ближе всего к местоположению пользователя.

К концу этого урока вы сможете:

  • Используйте Django для создания простого веб-приложения с нуля

  • Используйте подфреймворк GeoDjango для реализации геолокационных функций в вашем Django-приложении

  • Используйте пространственную базу данных (PostgreSQL и PostGIS), чтобы получить преимущества от пространственных функций и легко реализовать веб-приложения с учетом местоположения

Инструменты, которые вы будете использовать

Для разработки веб-приложения "Магазины поблизости" вы будете использовать следующие инструменты:

  • Язык программирования Python
  • Веб-фреймворк Django
  • База данных PostgreSQL для хранения данных
  • Расширение PostGIS для поддержки пространственных характеристик в базе данных PostgreSQL
  • pip для установки зависимостей
  • Модуль venv для управления виртуальной средой
  • Docker для установки PostgreSQL и PostGIS

Used tools

Прежде чем перейти к практическим шагам, давайте сначала познакомимся с фреймворками, которые вы будете использовать.

Django - самый популярный фреймворк на языке Python для создания веб-приложений. Он позволяет разработчикам быстро создавать прототипы и укладываться в сроки выполнения проектов благодаря множеству встроенных API и подфреймворков, таких как GeoDjango.

GeoDjango - это встроенное приложение, которое входит в Django в качестве contrib модуля. На самом деле это полноценный фреймворк, который можно использовать и отдельно от Django. Он предоставляет набор утилит для создания веб-приложений для ГИС.

GIS расшифровывается как Geographic Information System. Это информационная система (организованная система сбора, организации, хранения и передачи информации), предназначенная для обработки и манипулирования данными, имеющими географические или пространственные характеристики.

GeoDjango также предоставляет привязки на Python для популярных пространственных библиотек, таких как GEOS, GDAL и GeoIP, которые можно использовать отдельно без Django в любом приложении на Python или интерактивно в оболочке.

GeoDjango призван обеспечить географический веб-фреймворк мирового класса. На протяжении многих лет он подвергался рефакторингу с целью облегчить работу с геопространственными данными, то есть данными, которые определяют географическое положение природных или искусственных объектов на Земле и хранятся в виде координат и топологий.

GeoDjango очень хорошо интегрируется с Django ORM и предоставляет набор геометрических полей, определенных Open Geospatial Consortium (OGS), которые могут быть использованы для сопоставления с различными типами геометрии в геопространственных базах данных:

  • GeometryField - базовый класс для всех геометрических полей в GeoDjango.
  • PointField используется для хранения объектов GEOS Point.
  • PolygonField используется для хранения объектов GEOS Polygon и так далее.

GeoDjango - это очень мощный фреймворк для хранения и работы с географическими данными с помощью Django ORM. Он предоставляет простой в использовании API для поиска расстояний между двумя точками на карте, площадей многоугольников, точек внутри многоугольника и т. д.

Для работы с GeoDjango вам понадобятся две вещи: пространственная база данных и геопространственные библиотеки. пространственная база данных - это база данных, оптимизированная для хранения и запроса данных, которые представляют собой объекты, определенные в геометрическом пространстве.

Для того чтобы в полной мере использовать все возможности GeoDjango, вам потребуется установить следующие геопространственные библиотеки с открытым исходным кодом:

  • GEOS расшифровывается как Geometry Engine Open Source. Это порт JTS (Java Topology Suite) на C++, реализующий спецификацию OCG Simple Feature for SQL.

  • GDAL расшифровывается как Geospatial Data Abstraction Library. Это библиотека с открытым исходным кодом для работы с растровыми и векторными форматами геопространственных данных.

  • PROJ.4 - библиотека картографических проекций. Это ГИС-библиотека с открытым исходным кодом для удобной работы с пространственными системами отсчета и проекциями.

  • GeoIP - библиотека, которая помогает пользователям находить географическую информацию на основе IP-адреса.

В этом руководстве используется система Ubuntu 18.04 для установки предварительных условий и Unix bash для выполнения команд, но это не должно быть проблемой для вас, если вы используете любую другую систему, особенно основанную на Unix, например macOS.

В большинстве инструкций по установке вы будете использовать менеджер пакетов aptitude, поэтому вам следует просто заменить его на эквивалентный менеджер пакетов для вашей системы.

Пререквизиты

В этом разделе вы установите предварительные условия, необходимые для загрузки вашего проекта, такие как Python 3 и GeoDjango зависимости (GEOS, GDAL и PROJ.4). Вы также будете использовать Docker для установки базы данных PostgreSQL и PostGIS для вашего проекта.

Установка Python 3

Велика вероятность того, что в вашей системе уже установлен Python 3. Если нет, вы можете просто зайти на официальный сайт и скачать двоичные файлы для вашей операционной системы.

В зависимости от вашей системы, вы также можете установить Python 3 или обновить его до последней версии, если он уже установлен, используя официальный менеджер пакетов.

Если у вас возникли проблемы с установкой Python 3 или вам нужна дополнительная информация, вы можете посмотреть Python 3 Installation.

Наконец, вы можете проверить, установлен ли у вас Python 3, выполнив следующую команду:

$ python3 --version
Python 3.6.5

Установка зависимостей GeoDjango (GEOS, GDAL и PROJ.4)

Для работы GeoDjango требуется пространственная база данных и набор геопространственных библиотек с открытым исходным кодом:

  • GEOS - это геометрический движок с открытым исходным кодом и C++ порт JTS (Java Topology Suite). Он необходим GeoDjango для выполнения геометрических операций.

  • PROJ.4 - это ГИС-библиотека с открытым исходным кодом для удобной работы с пространственными системами отсчета и проекциями. Она нужна вам, потому что в качестве базы пространственных данных вы будете использовать PostGIS.

  • GDAL - это библиотека абстракций геопространственных данных с открытым исходным кодом для работы с растровыми и векторными форматами данных. Она необходима для многих утилит, используемых в GeoDjango.

Для получения дополнительной информации о пространственных базах данных и необходимых библиотеках вы можете обратиться к документации.

GDAL 2.2 включен в Ubuntu 18.04, поэтому для его установки можно просто выполнить следующую команду:

$ sudo aptitude install gdal-bin libgdal-dev
$ sudo aptitude install python3-gdal

Примечание: python3-gdal - это привязка Python 3 для GDAL.

Далее вы можете установить другие библиотеки, используя следующее:

$ sudo aptitude install binutils libproj-dev

Примечание: Поскольку вы используете бинарный пакет для GEOS, вам также необходимо установить binutils.

Обратитесь к документации за подробными инструкциями по установке этих зависимостей на macOS и Windows.

Для получения более подробной информации о PROJ.4 вы можете обратиться к его официальным документам.

Установка пространственной базы данных с помощью PostgreSQL и PostGIS

Вы будете использовать PostgreSQL, наиболее часто используемую базу данных с Django. Это не пространственная база данных, но благодаря PostGIS вы сможете дополнить свою базу данных мощными геопространственными функциями.

PostGIS - это расширение пространственной базы данных, которое необходимо установить на базу данных PostgreSQL, что дает ей возможность хранить и работать с пространственными данными и выполнять пространственные операции. Оно добавляет поддержку географических объектов, позволяя выполнять запросы на определение местоположения в SQL.

Вы можете либо установить PostgreSQL в своей системе, создать базу данных, а затем добавить расширение PostGIS, либо использовать Docker для быстрого создания базы данных с помощью образа kartoza postgis, который предоставляет контейнер с уже установленными PostgreSQL и PostGIS:

$ docker run --name=postgis -d -e POSTGRES_USER=user001 -e POSTGRES_PASS=123456789 -e POSTGRES_DBNAME=gis -p 5432:5432 kartoza/postgis:9.6-2.4

<<<После выполнения команды у вас появится сервер PostgreSQL, слушающий порт 5432 с базой данных gis. База данных использует имя пользователя user001 и пароль 123456789.

Примечание: В вашей системе должен быть установлен Docker. За инструкциями вы можете просто обратиться к официальным docs.

Установка проекта

Теперь, когда пространственная база данных настроена и готова, можно приступать к настройке проекта Django. В этом разделе вы воспользуетесь venv для создания изолированной виртуальной среды для вашего проекта и установите все необходимые пакеты, такие как Django.

Создание виртуальной среды

Виртуальное окружение позволяет создать изолированную среду для зависимостей текущего проекта. Это позволит вам избежать конфликтов между одними и теми же пакетами, имеющими разные версии.

В Python 3 вы можете создавать виртуальные среды с помощью virtualenv или модуля venv.

Для получения дополнительной информации о виртуальных средах Python, ознакомьтесь с Python Virtual Environments: A Primer.

Теперь перейдите в терминал и выполните следующую команду, чтобы создать виртуальную среду на основе Python 3:

$ python3 -m venv env
(env) $

Далее необходимо активировать следующую команду:

$ source env/bin/activate

Вот и все. Теперь у вас активирована виртуальная среда, и вы можете установить пакеты для вашего проекта.

Установка Django

Первым шагом после создания и активации виртуальной среды является установка Django. Пакет Django доступен из Python Package Index (PyPI), поэтому вы можете просто использовать pip для его установки, выполнив следующую команду в терминале:

$ pip install django

Создание проекта Django

Проект, который вы будете создавать, представляет собой веб-приложение, в котором перечислены магазины, отсортированные по расстоянию, так что ваши пользователи смогут найти магазины, которые находятся рядом с их местоположением.

Веб-приложение использует GeoDjango для простой реализации требований к местоположению, таких как вычисление расстояния до магазинов от местоположения пользователя и упорядочивание магазинов по расстоянию.

Используя GeoDjango, вы можете получить и отобразить ближайшие магазины, которые хранятся в базе данных PostgreSQL, настроенной с помощью расширения PostGIS, позволяющего выполнять пространственные операции.

Теперь вы готовы к созданию проекта Django с помощью скрипта django-admin.py. Просто выполните следующую команду:

$ django-admin.py startproject nearbyshops

Это создаст проект с именем nearbyshops.

Настройка базы данных PostgreSQL

Теперь, когда вы создали проект, давайте продолжим настройку подключения к пространственной базе данных PostgreSQL и PostGIS. Откройте файл settings.py и добавьте django.contrib.gis.db.backends.postgis в качестве движка с учетными данными для базы данных PostGIS, которую вы настроили ранее:

DATABASES = {
    'default': {
        'ENGINE': 'django.contrib.gis.db.backends.postgis',
        'NAME': 'gis',
        'USER': 'user001',
        'PASSWORD': '123456789',
        'HOST': 'localhost',
        'PORT': '5432'
    }
}

Примечание: Необходимо соответствующим образом изменить учетные данные базы данных, если вы не указали их при запуске контейнера Docker.

Если вы попытаетесь запустить свой Django-сервер на этом этапе, то получите ошибку ImportError: No module named 'psycopg2', связанную с psycopg2, который является наиболее популярным адаптером PostgreSQL для Python. Чтобы решить эту проблему, вам нужно просто установить psycopg2-binary в ваше виртуальное окружение, используя следующее:

$ pip install psycopg2-binary

Добавление GeoDjango

GeoDjango - это фреймворк, который максимально упрощает создание ГИС и веб-приложений с учетом местоположения. Вы можете добавить его, просто включив модуль gis contrib в список установленных приложений.

Откройте файл settings.py и найдите массив INSTALLED_APPS. Затем добавьте модуль 'django.contrib.gis':

INSTALLED_APPS = [
    # [...]
    'django.contrib.gis'
]

Создание приложения Django

Проект Django состоит из приложений. По умолчанию он содержит несколько основных или встроенных приложений, таких как django.contrib.admin, но обычно вы добавляете по крайней мере одно приложение, содержащее код вашего пользовательского проекта.

Примечание: Для простых проектов вам может понадобиться только одно приложение, но когда ваш проект станет больше и будет иметь различные требования, вы можете организовать свой код в нескольких отдельных приложениях.

Теперь, когда вы создали проект Django, настроили соединение с пространственной базой данных и добавили GeoDjango в проект, вам нужно создать Django-приложение, которое можно назвать shops.

Приложение shops будет содержать код для создания и отображения магазинов, ближайших к местоположению пользователя. В следующих шагах вам предстоит выполнить следующие задачи:

  • Создайте приложение
  • Добавьте Shop модель
  • Добавьте миграцию данных для загрузки начальных демо-данных (магазины)
  • Добавьте функцию представления
  • Добавить шаблон

Сначала выполните следующую команду, чтобы создать приложение:

$ python manage.py startapp shops

Далее вам нужно добавить его в список установленных приложений в файле settings.py, что заставит Django распознать его как часть вашего проекта:

INSTALLED_APPS = [
    # [...]
    'shops'
]

Создание модели Django

После создания приложения shops, которое будет содержать фактический код вашего проекта, вам необходимо добавить модели в ваше приложение. Django использует ORM (Object Relational Mapper), который представляет собой слой абстракции между Django и базой данных, преобразующий объекты Python (или модели) в таблицы базы данных.

В данном случае вам нужна одна модель, которая представляет магазин в базе данных. Вы создадите модель Shop, которая будет содержать следующие поля:

  • name: название магазина
  • location: местоположение магазина в координатах широты и долготы
  • address: адрес магазина
  • city: город, в котором находится магазин

Откройте файл shops/models.py и добавьте следующий код:

from django.contrib.gis.db import models

class Shop(models.Model):
    name = models.CharField(max_length=100)
    location = models.PointField()
    address = models.CharField(max_length=100)
    city = models.CharField(max_length=50)

Для местоположения вы используете PointField, специфическое для GeoDjango геометрическое поле для хранения объекта GEOS Point, который представляет собой пару координат долготы и широты.

Остальные поля - это обычные поля Django типа CharField, которые можно использовать для хранения строк маленького и большого размера.

Примечание: Обратите внимание, что модуль models импортируется из django.contrib.gis.db, а не из обычного модуля django.db.

Создание таблиц базы данных

Благодаря ORM в Django вам не нужно использовать SQL для создания таблиц базы данных. Давайте создадим таблицы базы данных с помощью команд makemigrations и migrate. Вернитесь в терминал и выполните следующие команды:

$ python manage.py makemigrations
$ python manage.py migrate

Для получения дополнительной информации об этих командах, ознакомьтесь с Django Migrations - A Primer.

Добавление суперпользователя

Вам необходимо создать суперпользователя, чтобы получить доступ к интерфейсу администратора. Это можно сделать с помощью следующей команды:

$ python manage.py createsuperuser

В ответ на запрос будет введено имя пользователя, электронная почта и пароль, которые вы хотите использовать для доступа к учетной записи пользователя. Введите их и нажмите Enter.

Регистрация модели в интерфейсе администратора

Админ-приложение Django предоставляет полный CRUD-интерфейс для управления данными.

GeoDjango расширяет приложение администратора, добавляя поддержку работы с геометрическими полями.

Прежде чем вы сможете получить доступ к своим моделям из админки Django, их нужно зарегистрировать.

Откройте файл shops/admin.py и добавьте следующий код:

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

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

Вы используете декоратор @admin.register для регистрации модели Shop в приложении администратора. Декоратор представляет собой представление модели Shop в интерфейсе администратора и позволяет настраивать различные аспекты, например поля Shop, которые вы хотите отображать. (В вашем случае это название и местоположение.) Для получения дополнительной информации о декораторах вы можете прочитать Пример по декораторам Python.

Поскольку модель Shop включает поле GeoDjango, необходимо использовать специальный класс OSMGeoAdmin, доступный из пакета django.contrib.gis.admin .

Вы можете использовать либо GeoModelAdmin, либо OSMGeoAdmin, который является подклассом GeoModelAdmin, использующим слой Open Street Map в админке для отображения геометрических полей. Это позволяет получить больше информации, например, подробные сведения об улицах и магистралях, чем можно получить с помощью класса GeoModelAdmin, который использует Vector Map Level 0.

Теперь вы можете запустить сервер Django:

$ python manage.py runserver

Ваше приложение будет запущено из localhost:8000, а доступ к интерфейсу администратора вы сможете получить из localhost:8000/admin.

Admin interface, shop app

Это скриншот из интерфейса Add shop:

Admin interface, add shop

Вы видите, что геометрическое поле Location отображается в виде интерактивной карты. Карту можно увеличивать и уменьшать, а также выбирать различные селекторы в правом верхнем углу карты, чтобы выбрать местоположение, которое отмечено зеленым кружком.

Добавление начальных данных

Вам нужны исходные демонстрационные данные для вашего приложения, но вместо того, чтобы добавлять их вручную, вы можете использовать миграцию данных.

Миграция данных может использоваться в различных сценариях, включая добавление исходных данных в вашу базу данных. Для получения дополнительной информации ознакомьтесь с Миграции данных.

Прежде чем создавать миграцию, давайте сначала получим некоторые реальные данные из OpenStreetMap с помощью overpass turbo, веб-инструмента фильтрации данных для OpenStreetMap. Вы можете выполнять Overpass API запросы и анализировать полученные данные в интерактивном режиме на карте.

Вы также можете использовать встроенный Wizard, который упрощает создание запросов.

В вашем случае вы хотите получить все магазины в городе. Просто нажмите на кнопку Wizard. Появится небольшое окно. В текстовом поле напишите запрос типа "магазин в Майами" и нажмите на build and run query.

Overpass turbo query

Далее нажмите на кнопку export и нажмите download/copy as raw OSM data, чтобы загрузить JSON-файл, содержащий необработанные OSM-данные. Сохраните файл как data.json в корневой папке вашего проекта:

Overpass turbo export

Это снимок экрана с примером данных из файла:

Overpass turbo data example

Вам нужно получить объекты в массиве elements. В частности, поля lat, lon и tags (name) для каждого магазина.

Подробнее о том, как писать запросы к Overpass, можно прочитать здесь wiki.

Теперь создадим пустую миграцию для импорта содержимого файла data.json в базу данных, используя следующую команду:

$ python manage.py makemigrations shops --empty

Откройте файл миграции. Он содержит следующий код:

from django.db import migrations

class Migration(migrations.Migration):
    dependencies = [
        ('shops', '0001_initial'),
    ]
    operations = [
    ]

Далее вам нужно создать load_data(), который будет выполняться RunPython(). Сначала в области импорта добавьте следующие импорты:

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

Вы импортируете класс Path из пакета pathlib для доступа к низкоуровневым системным функциям, пакета json для работы с JSON, встроенного в Django API миграций и fromstr(), входящего в пакет geos.

Далее добавьте load_data():

DATA_FILENAME = 'data.json'
def load_data(apps, schema_editor):
    Shop = apps.get_model('shops', '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     

Давайте объясним код, который вы только что добавили. Сначала вы определяете абсолютный путь с помощью класса Path библиотеки pathlib и открываете файл data.json. Далее вы разбираете JSON-файл на объекты Python.

Вы просматриваете объект elements, содержащий местоположение и теги магазинов. Внутри цикла вы извлекаете название и координаты долготы и широты. Затем с помощью formstr() возвращаете корректный объект GEOSGeometry, соответствующий пространственным данным в строке, который можно присвоить полю location модели Shop. Наконец, вы создаете и сохраняете экземпляр модели Shop, соответствующий извлеченным данным.

Вы используете оператор with, поэтому вам не нужно явно закрывать файл, и f-строку для форматирования аргумента fromstr().

fromstr() принимает srid в качестве второго параметра. srid означает идентификатор пространственной системы отсчета. Это уникальное значение для идентификации пространственных систем отсчета (систем проекций, используемых для интерпретации данных в пространственной базе данных).

4326 srid - самая популярная система, используемая в PostGIS. Она также известна как WGS84, где единицы измерения указываются в градусах долготы и широты. Вы можете обратиться к сайту spatialreference.org за базой данных пространственных систем привязки на основе Django.

Далее добавьте класс миграции для выполнения вышеуказанной функции при выполнении команды migrate:

class Migration(migrations.Migration):

    dependencies = [
        ('shops', '0005_auto_20181018_2050'),
    ]

    operations = [
        migrations.RunPython(load_data)
    ]

Вот и все. Теперь вы можете вернуться в терминал и выполнить следующее:

$ python manage.py migrate

Данные из файла data.json будут загружены в вашу базу данных. Запустите ваш Django-сервер и перейдите в интерфейс администратора. Вы должны увидеть свои данные в таблице. В моем случае это скриншот части таблицы:

Admin interface, list shops

Отображение близлежащих магазинов

На данном этапе обучения вы создали:

  • Приложение shops, в котором заключен код для создания и получения близлежащих магазинов в вашем проекте

  • Модель Shop и соответствующие таблицы в базе данных

  • Первоначальный пользователь-администратор для доступа к интерфейсу администратора

  • Начальные демонстрационные данные для загрузки реальных магазинов в базу данных, с которыми вы можете поиграть, не вводя вручную множество поддельных данных

Вы также зарегистрировали модель Shop в приложении администратора, чтобы иметь возможность создавать, обновлять, удалять и перечислять магазины из интерфейса администратора.

Далее вы добавите функцию просмотра, использующую общий класс ListView, которую можно использовать для отображения списка ближайших магазинов. Вы также создадите HTML-шаблон, который будет использоваться функцией просмотра для отображения магазинов, и добавите URL, который будет использоваться для отображения магазинов.

Для начала добавим шаблон и функцию просмотра, которая будет использоваться для отображения близлежащих магазинов по местоположению пользователя.

Откройте файл shops/views.py и начните с импорта необходимых API:

from django.views import generic
from django.contrib.gis.geos import fromstr
from django.contrib.gis.db.models.functions import Distance
from .models import Shop

Далее добавьте переменную user_location, в которой вы можете жестко закодировать местоположение пользователя:

longitude = -80.191788
latitude = 25.761681

user_location = Point(longitude, latitude, srid=4326)

В этой части вы просто введете местоположение пользователя (координаты Майами в США), но в идеале оно должно быть указано пользователем или получено автоматически из браузера пользователя с его разрешения с помощью JavaScript и HTML5 GeoLocation API. Вы можете прокрутить страницу вниз до середины, чтобы увидеть живой пример реализации Geolocation API.

Наконец, добавьте следующий класс представления:

class Home(generic.ListView):
    model = Shop
    context_object_name = 'shops'
    queryset = Shop.objects.annotate(distance=Distance('location',
    user_location)
    ).order_by('distance')[0:6]
    template_name = 'shops/index.html'

Вы используете общий класс на основе ListView для создания представления.

Представления на основе классов - это альтернативный способ реализации представлений в виде классов в Python вместо функций. Они используются для решения распространенных задач в веб-разработке, не изобретая велосипед. В этом примере вы только что создали подкласс общего представления ListView и переопределили атрибуты model, context_object_name, queryset и template_name, чтобы создать представление списка, которое обрабатывает HTTP-запросы без какого-либо дополнительного кода.

Теперь давайте сосредоточимся на атрибуте queryset. Чтобы получить ближайшие магазины, вы просто используете .annotate() для аннотации каждого объекта в возвращаемом наборе запросов с аннотацией расстояния, которое вычисляется с помощью Distance(), доступного из GeoDjango, между местоположением каждого магазина и местоположением пользователя. Вы также упорядочиваете возвращаемый набор запросов по аннотации расстояния и берете только шесть ближайших магазинов.

Вы можете узнать больше о представлениях на основе классов из официальных docs.

Далее добавим шаблон shops/index.html со следующим содержанием:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Nearby Shops</title>
    </head>
<body>
    <h1>Nearby Shops</h1>
    {% if shops %}
    <ul>
    {% for shop in shops %}
        <li>
        {{ shop.name }}: {{shop.distance}}
        </li>
    {% endfor %}
    </ul>
    {% endif %}
</body>
</html>

Ближайшие магазины доступны из объекта контекста shops, который вы указали в качестве context_object_name в представлении на основе класса. Вы перебираете объекты shops и выводите название и расстояние от местоположения пользователя для каждого магазина.

Наконец, давайте добавим URL к нашему urls.py файлу:

from django.urls import path
from shops import views

urlpatterns = [
    # [...]
    path('', views.ShopList.as_view())
]

Вы используете .as_view(), чтобы вернуть вызываемый вид, который принимает request и возвращает response, который может быть передан в качестве второго параметра для path(), сопоставляющего пути с видами.

Теперь вы можете запустить свой сервер Django. На главной странице будет отображаться простой нестилизованный список с ближайшими магазинами от жестко заданного местоположения пользователя. Вот пример скриншота:

Nearby shops

На скриншоте каждый элемент списка отображает название магазина (перед двоеточием) и расстояние в метрах от местоположения пользователя (после двоеточия). Буква m обозначает метры.

Примечание: Функция view, которую вы использовали для отображения результатов на скриншоте, предназначена только для тестирования набора запросов, аннотированного Distance().

На этом мы завершаем данный учебник. Теперь у вас есть базовые навыки, которые вы можете использовать для добавления простых геолокационных функций в ваши приложения или для создания ГИС-приложений. Вы можете прочитать GeoDjango docs для получения полной информации о доступных API и о том, что вы можете с ними делать.

Вы также научились использовать Docker для быстрого извлечения и запуска сервера PostgreSQL и PostGIS. Docker можно использовать не только для этого. Это инструмент контейнеризации для создания изолированных, воспроизводимых сред приложений. Вы можете прочитать Django Development with Docker Compose and Machine, если хотите узнать, как контейнеризировать свой Django-проект.

Заключение

Поздравляем вас с созданием веб-приложения, основанного на определении местоположения, с помощью GeoDjango, который призван стать географическим фреймворком мирового класса для реализации ГИС-приложений. В настоящее время приложения с привязкой к местоположению (приложения, которые знают ваше местоположение и помогают вам обнаружить близлежащие объекты и услуги, предлагая вам результаты, основанные на вашем местоположении) - это все большая популярность. Используя знания, полученные в этом уроке, вы сможете внедрить эту современную функцию в свои приложения, разработанные на Django.

Единственным требованием, помимо зависимостей GeoDjango, является использование пространственной базы данных (базы данных, способной хранить и манипулировать пространственными данными). Для PostgreSQL, одной из самых популярных систем управления базами данных, используемых с Django, вы можете просто установить расширение PostGIS вместе с вашей базой данных, чтобы превратить ее в пространственную базу данных. Другие популярные базы данных, такие как Oracle и MySQL, имеют встроенную поддержку пространственных данных.

В этом уроке вы использовали:

  • Django для создания веб-приложения с нуля
  • Подфреймворк GeoDjango для реализации геолокационных функций в вашем Django-приложении
  • Пространственная база данных, PostgreSQL и PostGIS, для получения преимуществ от пространственных функций и реализации веб-приложений с учетом местоположения

У вас есть приложение на Django, которое может выиграть от того, что будет лучше понимать местоположение? Попробуйте GeoDjango и поделитесь своим опытом в комментариях ниже.

Исходный код примера приложения: Полный исходный код приложения, которое вы создавали в этом учебнике, доступен в репозитории realpython/materials на GitHub.

Вернуться на верх