Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions .github/workflows/python-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ concurrency:
cancel-in-progress: true

jobs:
lint:
quality:
runs-on: ubuntu-latest

steps:
Expand All @@ -26,13 +26,17 @@ jobs:
with:
python-version: "3.10"

- name: Install flake8
- name: Install ruff
run: |
python -m pip install flake8 -U
python -m pip install ruff -U

- name: Lint with flake8
- name: Check linting
run: |
flake8 mapentity test_project test_app
ruff check mapentity test_project

- name: Check format
run: |
ruff format --check mapentity test_project

test:
runs-on: ubuntu-latest
Expand All @@ -44,10 +48,10 @@ jobs:
strategy:
matrix:
python-version: [ '3.9', '3.10', '3.13' ]
django-version: [ '4.2.*', '5.2' ]
django-version: [ '4.2.*', '5.2.*' ]
exclude:
- python-version: '3.9'
django-version: '5.2'
django-version: '5.2.*'

env:
PYTHON: ${{ matrix.python-version }}
Expand Down Expand Up @@ -89,7 +93,7 @@ jobs:
fail_ci_if_error: true # optional (default = false)

publish:
needs: [lint, test]
needs: [quality, test]
runs-on: ubuntu-latest
permissions:
id-token: write
Expand Down
4 changes: 3 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
CHANGELOG
=========

8.13.0+dev (XXXX-XX-XX)
8.13.1 (2025-07-16)
-----------------------

- Use logout view in POST (https://code.djangoproject.com/ticket/15619)


8.13.0 (2025-04-29)
-----------------------
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ RUN apt-get update -qq && apt-get install -y -qq \
binutils libproj-dev gdal-bin libsqlite3-mod-spatialite \
libjpeg62 zlib1g-dev libcairo2 libpango-1.0-0 \
libpangocairo-1.0-0 libgdk-pixbuf2.0-0 libffi-dev shared-mime-info \
libldap2-dev libsasl2-dev && \
libldap2-dev libsasl2-dev gettext && \
apt-get clean all && rm -rf /var/apt/lists/* && rm -rf /var/cache/apt/*

RUN mkdir -p /code
Expand Down
18 changes: 12 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,20 @@ serve:
###########################
# Lint #
###########################
.PHONY: format
format:
$(docker_compose) run --remove-orphans --no-deps --rm web ruff format mapentity test_project

.PHONY: check-flake8
check-flake8:
@$(PRINT_COLOR) "$(COLOR_SUCCESS) \n### check-flake8 ###\n $(COLOR_RESET)\n"
$(docker_compose) run --rm web flake8 mapentity test_project test_app
.PHONY: lint
lint:
$(docker_compose) run --remove-orphans --no-deps --rm web ruff check --fix mapentity test_project

.PHONY: check-lint
check-lint: check-flake8
.PHONY: force_lint
force_lint:
$(docker_compose) run --remove-orphans --no-deps --rm web ruff check --fix --unsafe-fixes mapentity test_project

.PHONY: quality
quality: lint format

###########################
# Test #
Expand Down
57 changes: 55 additions & 2 deletions docs/customization.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,29 @@ Customization
=============


Models
------

If you want to add some custom fields in the list view, you must customize your model

from django.utils.functional import classproperty

class Museum(MapEntityMixin, models.Model):
geom = models.PointField()
name = models.CharField(max_length=80)

# create a property for you custom column
@property
def my_custom_col(self):
<my custim logic>

# Map entity need a verbose name to display the custom column in the table
@classproperty
def my_custom_col_verbose_name(cls):
return "My custom label"



Views
-----

Expand All @@ -13,8 +36,10 @@ can override CBV methods as usual::
from mapentity.views.generic import (
MapEntityList, MapEntityDetail,
MapEntityFormat, MapEntityCreate, MapEntityUpdate, MapEntityDocument,
MapEntityDelete, MapEntityViewSet)
MapEntityDelete)
from .models import Museum
from mapentity.views.api import MapEntityViewSet

from .serializers import MuseumSerializer


Expand All @@ -24,7 +49,7 @@ can override CBV methods as usual::

class MuseumList(MapEntityList):
model = Museum
columns = ['id', 'name']
columns = ['id', 'name', 'my_custom_col']


class MuseumDetail(MapEntityDetail):
Expand Down Expand Up @@ -54,8 +79,36 @@ can override CBV methods as usual::
class MuseumViewSet(MapEntityViewSet):
model = Museum
serializer_class = MuseumSerializer
geojson_serializer_class = MuseumGeojsonSerializer

queryset = Museum.objects.all()



Serializers
------------

You must define a least a regular and a geosjon serializer::


from rest_framework import serializers
from mapentity.serializers import MapentityGeojsonModelSerializer


from .models import Museum

class MuseumSerializer(serializers.ModelSerializer):
class Meta:
fields = "__all__"
model = Museum

class MuseumGeojsonSerializer(MapentityGeojsonModelSerializer):
class Meta(MapentityGeojsonModelSerializer.Meta):
# the custom field must be added to the serializer
my_custom_field = serializers.CharField()

fields = ["id", "name", "my_custom_field"]
model = Museum

Filters
-------
Expand Down
28 changes: 25 additions & 3 deletions docs/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,29 @@ processors::
'context_processors': [
"django.core.context_processors.request",
"mapentity.context_processors.settings",
]
}
}
]


Add the `MAPENTITY_CONFIG` variable::

MAPENTITY_CONFIG = {}

Define a configuration for leaflet::

LEAFLET_CONFIG = {
'SRID': 3857,
'TILES': [
('OSM', 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', '(c) OpenStreetMap Contributors'),
('OSM N&B', 'http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png', '(c) OpenStreetMap Contributors'),
],
# 'SPATIAL_EXTENT': (1.3, 43.7, 1.5, 43.5),
}


Model
-----

Expand Down Expand Up @@ -122,7 +137,10 @@ Register your MapEntity views in ``main/urls.py``:
.. code-block:: python

from main.models import Museum
from mapentity import registry
from mapentity.registry import registry

app_name = "main"


urlpatterns = registry.register(Museum)

Expand All @@ -133,16 +151,20 @@ Then glue everything together in your project's ``urls.py``:

from django.conf.urls import patterns, include, url
from django.contrib import admin
from django.contrib.auth import views as auth_views

admin.autodiscover()

urlpatterns = [
'',
path('', 'main.views.home', name='home'),
path('', RedirectView.as_view(url=reverse_lazy('main:museum_list'), permanent=True), name='home'),
path('login/', 'django.contrib.auth.views.login', name='login'),
path('logout/', 'django.contrib.auth.views.logout', name='logout',),
path('', include('mapentity.urls')),
path('paperclip/', include('paperclip.urls')),
path('i18n/', include('django.conf.urls.i18n')),
path('login/', auth_views.LoginView.as_view(), name='login'),
path('logout/', auth_views.LogoutView.as_view(), {'next_page': '/'}, name='logout',),
path('admin', admin.site.urls),
]

Expand Down
2 changes: 1 addition & 1 deletion mapentity/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8.13.0+dev
8.13.1
5 changes: 3 additions & 2 deletions mapentity/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# Make sure mapentity settings are loaded before leaflet ones
import os

from . import settings # noqa

here = os.path.abspath(os.path.dirname(__file__))

with open(os.path.join(here, 'VERSION')) as version_file:
with open(os.path.join(here, "VERSION")) as version_file:
VERSION = version_file.read().strip()

default_app_config = 'mapentity.apps.MapEntityConfig'
default_app_config = "mapentity.apps.MapEntityConfig"
__version__ = VERSION
23 changes: 13 additions & 10 deletions mapentity/context_processors.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
from django.conf import settings as settings_ # import the settings file

from mapentity import __version__

from .registry import registry
from .settings import app_settings


def settings(request):
allowed_entities = [
entity for entity in registry.entities
if request.user.has_perm(entity.model.get_permission_codename('list'))
entity
for entity in registry.entities
if request.user.has_perm(entity.model.get_permission_codename("list"))
]
return dict(
TITLE=app_settings['TITLE'],
TITLE=app_settings["TITLE"],
DEBUG=settings_.DEBUG,
VERSION=getattr(settings_, 'VERSION', __version__),
JS_SETTINGS_VIEW=app_settings['JS_SETTINGS_VIEW'],
TRANSLATED_LANGUAGES=app_settings['TRANSLATED_LANGUAGES'],
VERSION=getattr(settings_, "VERSION", __version__),
JS_SETTINGS_VIEW=app_settings["JS_SETTINGS_VIEW"],
TRANSLATED_LANGUAGES=app_settings["TRANSLATED_LANGUAGES"],
MODELTRANSLATION_LANGUAGES=settings_.MODELTRANSLATION_LANGUAGES,
MAP_BACKGROUND_FOGGED=app_settings['MAP_BACKGROUND_FOGGED'],
MAP_FIT_MAX_ZOOM=app_settings['MAP_FIT_MAX_ZOOM'],
ACTION_HISTORY_ENABLED=app_settings['ACTION_HISTORY_ENABLED'],
MAX_CHARACTERS=app_settings['MAX_CHARACTERS'],
MAP_BACKGROUND_FOGGED=app_settings["MAP_BACKGROUND_FOGGED"],
MAP_FIT_MAX_ZOOM=app_settings["MAP_FIT_MAX_ZOOM"],
ACTION_HISTORY_ENABLED=app_settings["ACTION_HISTORY_ENABLED"],
MAX_CHARACTERS=app_settings["MAX_CHARACTERS"],
allowed_entities=allowed_entities,
)
Loading