09 Jul 2026

feedDjango community aggregator: Community blog posts

Foss4g NL: early afternoon sessions

(One of my summaries of the 2026 one-day Foss4g open source geo conference in Groningen, NL).

Accessibility: geoinformation for everybody - Liliana Santoso-Avis & Jedidja van der Sluis - Stoutjesdijk

WCAG (Web Content Accessibility Guidelines) deals with accessibility (a11y). (I personally try to take accessibility a bit into account, proper headings and reasonably contrast-rich colors on my website, for instance. I've made other summaries of "a11y" talks, for instance this one about accessible documentation, held at the 2025 pycon.de.

It is not just accessibility, but really about the quality of the information as a whole. Thinking about the accessibility guidelines (listed below) helps you create better information projects.

  • Perceivable
  • Operable, for instance navigating a website with keyboard instead of mouse.
  • Understandable
  • Robust

When making a map viewer, we often claim "we're an exception", but that's not fully the case. Your map component should not be a "keyboard trap", for instance. And the contrast of your map should be right. And if the map is essential for navigating through the rest of the site, you also can't claim an exception.

You need a mindset shift. From "bah, extra work" to "hurray, better work".

They started with an inventory, for instance of the applicable laws. Then getting the roles/responsibilities right. Then lots of experience sharing. Now they want to get certification for the work they did. And they want to do outreach. And they now try to cooperate with partners (like other provinces and government agencies), software companies and other organisations.

In tourist areas, you sometimes have tactile maps. You can also do that in Qgis! You can print those maps. https://touch-mapper.org/en/

Colors: don't use only colors to indicate differences. Also differ the shapes of points, for instance. As a test, try to sort M&Ms while wearing colored glasses...

Some browser tools: taba11y to show the tab order of your site. Color contrast checker, heading map, leat's get color blind, link checker, WCAG color contrast checker.

GeoNode: digital sovereignty in practice - Finn Peranovich & Guido Schaepman

Two Dutch water boards, Rijnland and Schieland en de Krimpenerwaard, cooperated in a project to move to open source with GeoNode.

They did an inventory in 2024 whether open source was an option. They looked at the current usage and identified possible open source alternatives. Open source promised more autonomy (no ESRI lock-in, geopolitical, etc.), lower costs (the costs of switching would be paid back within three years), more innovation and better compliance (both NL and EU laws).

The first test was with public-facing data that previously was served with ArcGIS server.

Geonode is a management layer on top of geoserver. It uses open source tools like Django, Mapstore, Postgresql, RabbitMQ. They run Geoserver and GeoNode inside a kubernetes cluster. Conversion from ArcGIS server was done with several homemade scripts.

Tip: Qgis has a handy Geonode plugin for browsing everything in your Geonode.

They were surprised by the quality of GeoNode: everything they needed from ArcGIS server is also available in GeoNode. They're currently in the test phase, they'll soon go to production. They really want to make other water boards enthusiastic about open source, too, hopefully leading to cost sharing.

https://reinout.vanrees.org/images/2026/straalzender2.jpeg

Unrelated photo: we have two offices in the center of Utrecht. As a handy connection, we're using a radio link ("straalverbinding") between the two. We have line of sight, as you can see in this photo. The dark gray wall to the right of the far radio link doesn't look like much, but it is part of our office and part of one of the oldest buildings (around 1200!) in Utrecht. (See wikipedia).

09 Jul 2026 4:00am GMT

08 Jul 2026

feedDjango community aggregator: Community blog posts

A small proposal to form rendering in Django

It's been a while since my last post, mainly because June saw me start a new client, GSOC really taking off and we have our first real customers in Hamilton Rock with money being deposited and some money being spent, not without its teething issues! Also with a fair amount of social engagements as well!

But anyway, on to today's post. During June I proposed a new feature idea which is an extension to Django's form rendering capabilities to include widgets templates inside a form renderer. Currently, it's only possible to Override widgets at a project level by specifying the template name, or you have to overwrite the widget and then specify your own custom template name and then use that custom widget. It's not possible to customize widgets at the form renderer level.

My idea is to extend the form renderer API. Well actually extends the budget rendering API to check the specified form renderer. It should only be an extension to a private method inside the widget API. Below is the relevant code that I actually got Claude to spit out inside Hamilton Rock today. This is a first iteration which very likely needs some improvement, but it does work!

_CAMEL_BOUNDARY = re.compile(r"(?<!^)(?=[A-Z])")

class Widget(metaclass=MediaDefiningClass):
    ...
    
    def _render(self, template_name, context, renderer=None):
        if renderer is None:
            renderer = get_default_renderer()
        # Walk the widget MRO for a ``<widget>_template_name`` on the renderer.
        # A class that defines its own ``template_name`` short-circuits (attribute
        # shadowing): a custom widget keeps its template over a base override,
        # while an unstyled subclass resolves up to a styled base.
        for klass in type(self).__mro__:
            slug = _CAMEL_BOUNDARY.sub("_", klass.__name__).lower()
            override = getattr(renderer, f"{slug}_template_name", None)
            if override is not None:
                template_name = override
                break
            if "template_name" in klass.__dict__:
                break
        # Same trust posture as Django's own Widget._render.
        return mark_safe(renderer.render(template_name, context))  # noqa: S308

and here is the current method from the source

    def _render(self, template_name, context, renderer=None):
        if renderer is None:
            renderer = get_default_renderer()
        return mark_safe(renderer.render(template_name, context))

There is also some code to allow admin classes to specify a renderer so that your custom renderer doesn't overwrite admin form widgets. In the coming week or so, I will extract this code into a third-party package for others to use.

But what's the real win with this potential change? Honestly I see this unlocking simple packages which unlock custom and complete form rendering packages with Django. Most of these themes would be HTML, CSS & Javascript, with the only python being the declaration of the FormRenderer class like so (pulled from Hamilton Rock):

class DrawerFormRenderer(TemplatesSetting):
    form_template_name = "forms/drawer_form.html#form"
    field_template_name = "forms/drawer_form.html#field"

    text_input_template_name = "forms/drawer_form.html#text_input"
    email_input_template_name = "forms/drawer_form.html#text_input"
    password_input_template_name = "forms/drawer_form.html#text_input"
    date_input_template_name = "forms/drawer_form.html#text_input"
    number_input_template_name = "forms/drawer_form.html#number_input"
    select_template_name = "forms/drawer_form.html#select"
    textarea_template_name = "forms/drawer_form.html#textarea"
    checkbox_input_template_name = "forms/drawer_form.html#checkbox"
    radio_select_template_name = "forms/drawer_form.html#radio"

If you like the look of this, give the feature a thumbs up on the issue and we can hopefully get it progressed. Also do let me know what glaring holes that I have missed in this idea.

08 Jul 2026 5:00am GMT

03 Jul 2026

feedDjango community aggregator: Community blog posts

Issue 344: Happy Birthday Djangonaut Space!

03 Jul 2026 3:00pm GMT