SmartQuery /ВОПРОС → ПРИМЕР → ПОНЯТНЫЙ ОТВЕТ
Базы данных

GeoDjango: геоданные и ближайшие объекты

GeoDjango входит в Django как django.contrib.gis. Это не отдельный пакет, который следует устанавливать командой pip install geodjango. Кроме Django, нужны зависимости выбранного географического backend.

Настройка проекта

Для PostgreSQL с пространственными данными обычно используют PostGIS. Установите подходящие версии PostgreSQL/PostGIS и системных GIS-библиотек по документации своей ОС, затем добавьте приложение django.contrib.gis. Backend указывается так:

DATABASES = {
    "default": {
        "ENGINE": "django.contrib.gis.db.backends.postgis",
        # NAME, USER, PASSWORD, HOST — из конфигурации среды
    }
}

Это фрагмент настройки, а не готовые реквизиты подключения. Создание расширения PostGIS требует соответствующих полномочий; миграции приложения не заменяют подготовку сервера.

Модель точки

from django.contrib.gis.db import models

class Place(models.Model):
    name = models.CharField(max_length=255)
    location = models.PointField(srid=4326)

Ближайший объект

from django.contrib.gis.geos import Point
from django.contrib.gis.db.models.functions import Distance
from .models import Place

# В SRID 4326: X — долгота, Y — широта
origin = Point(37.6156, 55.7522, srid=4326)
nearest = (Place.objects
           .annotate(distance=Distance("location", origin))
           .order_by("distance").first())

Модель названа Place, чтобы не затенять GEOS Point. Результат first() может быть None, если таблица пуста. Для больших наборов проверьте подходящий пространственный индекс и план запроса, а не предполагайте, что вычисление расстояния по всем строкам достаточно быстро.

Документация