Library / SDK
makinacorpus/django-leaflet avatar
makinacorpus/django-leaflet

django-leaflet: maps and geometry editing for Django without a spatial database

Use Leaflet in your Django projects

748 stars281 forksJavaScriptLGPL-3.0

At a glance

What is it?
django-leaflet embeds Leaflet 1.9.3 into Django projects and adds a geometry form widget, so you can draw and edit shapes on a map and store them as fields. It has one runtime dependency, Django, and it can be used with plain model fields or with django-geojson.
Who is it for?
Adopt django-leaflet if you need a map picker in a Django admin or a public form and you want to keep the geometry in ordinary model fields rather than setting up a spatial database, since the package adds Leaflet and a geometry widget with only Django as a runtime dependency.
Can I use it commercially?
Yes, with conditions. LGPL-3.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
Is it still maintained?
Yes. The repository last received commits 67 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What a Python package for a JavaScript library is actually for

django-leaflet allows you to use Leaflet in your Django projects, and the README explains the reasoning behind having a Python package at all in a list of five purposes.

The first is the plain install-and-enjoy path, which is the least interesting. The second is the one that bites every project: do not embed Leaflet assets in every Django project. Without a package, every application that wants a map ends up carrying its own copy of the Leaflet JavaScript and CSS, and the versions drift apart.

The third purpose is geometry editing with a Leaflet form widget, and this is the feature the rest of the package exists to support. A user draws a polygon or a line on a map, and the shape comes back as a value you can store in a model field.

The fourth is controlling the appearance and settings of maps from Django settings, for example at deployment time. The fifth is reusing Leaflet map initialization code, with local projections given as the example. That last one is a small feature with a large effect, because the initialization code is the part of a Leaflet map that is normally copy-pasted into every template, and centralising it means one change reaches every map.

The package is LGPL-3.0, which is the lesser copyleft licence, and the licence section also records the Leaflet copyright for CloudMade and Vladimir Agafonkin, which is the attribution Leaflet itself requires.

The default branch is master, and the last push was on 2026-08-17.

The version story, which is the confusing part

There is a discrepancy in the version information that anyone adopting this package should notice before they file a bug about it.

The release history lists 0.18.0 on 2016-01-04, 0.19.0 on 2016-08-22 and 0.20.0 on 2017-01-27. The last tagged release in that list is nearly a decade old. But the project metadata in the repository says the version is 0.34.1dev, and the repository has been pushed to as recently as 2026-08-17.

The dev suffix explains the pattern. The project is clearly still in active development on the master branch, but the tags listed as releases in the repository listing are old, so the published versions on PyPI and the development version in the tree are not in step with each other in the way the release list suggests. A reader who installs from PyPI and a reader who clones the repository may be on quite different code, and the Leaflet version embedded in the package is 1.9.3 in the current tree.

The practical advice is to check the CHANGES file in the repository before you upgrade, since that is the changelog the project points to from the project URLs in its metadata, alongside the documentation site at django-leaflet.readthedocs.io. If you are pinning a version for a production deployment, the dev suffix is a signal to read the changelog carefully rather than to assume a released artifact exists for the features you want.

There is also an example/ directory in the tree with a manage.py, a README, a requirements.txt and a mushrooms/ application, plus a quicktest.py at the top level, which together suggest there is a runnable example project you can use to check the package against a real Django setup.

The package itself is one Django app with one dependency

The build configuration tells you how small this is. The build backend is setuptools with a requirement of setuptools 64 or newer, the package list is just leaflet, and the runtime dependencies are django and nothing else.

One dependency is worth pausing on. django-leaflet does not depend on Leaflet as a Python package, because Leaflet is a JavaScript library that gets embedded rather than imported. The Leaflet assets live in the leaflet/ directory at the top of the repository, and the README states that the package embeds Leaflet version 1.9.3. That is the difference between a Python package that vendors a JavaScript library and one that only wires it up, and it is why the dependency list can be a single entry.

The Python side requires 3.10 or newer, and the classifiers list Python 3.10 through 3.14 with a 3.0-only marker, plus a Development Status of 5, Production/Stable. The classifiers also mark the package as usable in a Web Environment and as a Django framework package, which is the standard way to advertise on PyPI.

The maintainer is listed as Gagaro and the original author as Mathieu Leplatre of Makina Corpus, and the LICENSE file, the COPYRIGHT file and a CHANGES file sit at the top level alongside the README.rst. There is a tox.ini for running the test matrix and a .coveragerc for coverage configuration, and a docs/ directory holding the documentation that the readthedocs badge points at.

Geometry storage without a spatial database

The note in the README is the one that changes how you should use the package. django-leaflet is compatible with django-geojson fields, which allow handling geographic data without a spatial database.

That is a real architectural choice rather than a limitation being papered over. The Leaflet widget gives you a shape, and the question is where the shape lives. The obvious answer is a PostGIS column with a spatial index and spatial queries, which is the right answer for anything doing proximity searches, containment queries or spatial joins.

The django-geojson route stores the geometry as GeoJSON in an ordinary field. That means no spatial database, no PostGIS extension, no migration of your database, and the data stays readable with standard tools. What you give up is the ability to ask the database spatial questions, because a plain text column of GeoJSON cannot be indexed or queried spatially without the extensions that this approach is designed to avoid.

So the two paths divide cleanly. If you need a map picker and the geometry is a payload rather than a query subject, GeoJSON in a standard field is the simpler design. If your application needs to find all the polygons within a kilometre of a point, you need a spatial database and this package is only the widget that gets you the shape in the first place.

The README also lists the compatible package by link, and both projects are maintained by the same organisation, which is the sort of pairing that makes the choice easy to evaluate: install one and you have a coherent story rather than a widget bolted onto a mismatched data layer.

Where django-leaflet is the wrong tool

The first wrong case is a project that has already standardised on another map approach. Django has its own geographic model with PostGIS, and there are other Python mapping packages. If your organisation has a house style for maps, or if your forms already use a different geometry widget, a second widget is a second set of validation rules, a second JavaScript asset to load and a second thing to debug when a polygon will not save.

The second is a project that needs server-side spatial queries. As noted, the GeoJSON field approach cannot answer them, and this package is not a spatial database layer. If your requirement is spatial indexing, spatial joins or a bounding box query in SQL, that is a different piece of software and the widget does not change it.

The third is a project that needs a rich mapping interface rather than a picker. django-leaflet gives you a map with geometry editing and configurable initialisation. It is not a data visualisation layer, a clustering library, a heatmap or a routing engine, and the Leaflet plugin ecosystem is where those live.

The fourth is a team that needs a predictable release. The gap between a dev version in the tree and a release list whose newest entry is from 2017 is a real operational question, and it is the one to settle before you depend on this in a pipeline with a pinned version. Read the CHANGES file, decide whether you are tracking the branch or a published artifact, and be explicit about it.

The last point is about the licence. LGPL-3.0 is a fine licence for most use, and it is more permissive than GPL for a Django library, but it does have conditions around how you distribute it, and the Leaflet attribution obligation applies as well.

Editorial conclusion

Adopt django-leaflet if you need a map picker in a Django admin or a public form and you want to keep the geometry in ordinary model fields rather than setting up a spatial database, since the package adds Leaflet and a geometry widget with only Django as a runtime dependency. Keep away if you need PostGIS queries and spatial indexing, because this package is about the editing and display layer rather than the storage layer, and django-geojson is the companion for the data model. Before you upgrade, check the CHANGES file in the repository, since the project version in pyproject.toml is 0.34.1dev while the last published release listed is 0.20.0 from 2017, and the last push was on 2026-08-17.

Frequently asked questions

What does django-leaflet give me that plain Leaflet in a Django template does not?

The README lists five purposes: avoiding embedding Leaflet assets in every Django project, a geometry editing form widget, controlling map appearance and settings from Django settings, and reusing map initialization code such as local projections. The geometry widget is the substantial one, since it turns a drawn shape into a stored field value.

Which Leaflet version does django-leaflet embed?

The README states that the package embeds Leaflet version 1.9.3, with the assets vendored in the leaflet/ directory of the repository. The package has no Python dependency on Leaflet because it is embedded rather than imported.

Do I need PostGIS to use django-leaflet?

No. The package is compatible with django-geojson fields, which allow handling geographic data without a spatial database. If you need server-side spatial queries or spatial indexing, you would need a spatial database, and the geometry widget does not replace that layer.

What are the version and dependency requirements of django-leaflet?

The project metadata declares version 0.34.1dev, requires Python 3.10 or newer, and lists django as its only runtime dependency, with the build backend being setuptools at version 64 or newer. The classifier marks the project as Production/Stable and as a Django framework package.

Official sources

  1. Issues
  2. License: LGPL-3.0
  3. makinacorpus/django-leaflet on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/makinacorpus-django-leaflet.svg)](https://hysenlabs.com/projects/makinacorpus-django-leaflet)

Was this useful?