04 Feb 2025
Django community aggregator: Community blog posts
Built with Django Newsletter - 2025 Week 6
Hey, Happy Thursday!
Why are you getting this: *You signed up to receive this newsletter on Built with Django. I promised to send you the latest projects and jobs on the site as well as any other interesting Django content I encountered during the month. If you don't want to receive this newsletter, feel free to unsubscribe anytime.
News and Updates
- Last few weeks have been pretty good in terms of personal productivity, so I allowed myself some time to play around with LLMs. The results were quite good. If you are curious about my work and content I produce, you can subscribe to my personal newsletter.
- First thing that came out of it is the post about Django Updates in January 2025. I wrote some code that gets all the commit from the django repo from January, summarizes each one with AI and then creates a master summary with all the important details. I would love to hear your feedback about it, if any. I will keep iterating over it to improve. Even thinking about making a separate product out of it.
- I started dabbling in a new project which is top secret for now. Just kidding... I'm thinking of creating a web app that will help me come up with creative ways of sharing my projects, blog posts and other work on the internet (directories, link aggregators, social media, etc), using specific voice for each place. This means that
- I'm back to updating the django-saas-starter. If you ever end up using it, feel free telling me about your experience. I'm trying to make it as easy to use as possible. I'm probably going to make it paid at some point. Just as an FYI, though I'm not 100% sure about it.
- Anyway... Sorry for the rambling. Let's get into this week's issue.
Sponsors
This issue is sponsored by SEO Blog Bot. Well, sponsor is a strong word. It is just another project of mine that I wanted to share with you 🙈. Fully free!
If you have a side project and are struggling with finding ideas for blog posts, this will help!
If you want to become a real sponsor, just reply to this email or check out available options here.
Projects
- Design Studio Manager - Business management software for interior design studios. Handles the entire back of office workflow, including proposal, procurement, invoicing, reporting and managing work in progress.
- SoundMadeSeen - SoundMadeSeen is a tool that allows podcasters to create videos from their audio content
- Freelancer Dashboard - A CRM, assignment/to do list tracker, and automated invoicing platform for freelancers.
- No Nonsense Recipes - Just the recipes, no long storie
- Bank Statement Analyzer - Analyze your spending patterns with AI
- ShareMySnaps - Create and Share Stunning Digital Albums In Minute
- Online Convert Pro - Free Online Tools for Simple, Creative, Easy
- Django WTF - Django Packages Index
- FotoIA - Turn your selfies into professional photos or fantastic portraits with AI - in minutes!
Jobs
From the Community
- Managing Django's Queue by Carlton Gibson - Django's queue is overloaded and slowing everything down. The GitHub effect pushes too many extractive contributions onto a few core maintainers. A federated model would spread out the work and keep the community open and healthy.
- Avoiding Mocks: Testing LLM Applications with LangChain in Django - This article discusses a testing approach for Django projects that use large language models (LLMs) without relying on mocks. It suggests using a test-specific LLM backend to define responses and inspect requests, improving test reliability and maintainability. The approach allows for better isolation of tests and avoids common pitfalls associated with mocking.
- An Introduction to Django Views by Evgenia Verbina - Django views are essential for handling web requests and rendering templates in Django applications. There are two types of views: function-based views, which are simple and straightforward, and class-based views, which offer more structure and reusability. Understanding how to effectively use views will help you develop your Django projects more efficiently.
- (Re)naming things is hard by Eric Matthes - Renaming a widely used part of a project takes significant work. The author changed "simple_deploy" to "django_simple_deploy," which required thorough updates to code, documentation, and tests. They suggest prioritizing clear, consistent names early on and revisiting them if needed to help new users and contributors.
- What Changed? by Evan Rupert - The author uses a new project to refine workflows, switching from Make to Task, mandating an abstract base model for consistency, and focusing heavily on test coverage. He also reduces friction by integrating tests directly within the development environment. Yet he continues using Django Rest Framework and factoryboy, as they still provide rapid, reliable API and test development.
- What is OpenTelemetry and how to add it to your Django application by Jessica Garson - OpenTelemetry is an open-source framework that helps you monitor applications like Django in a standardized way. This blog post provides a guide on how to set up OpenTelemetry with a Django to-do list app and connect it to Elastic for observability. You can choose between automatic and manual instrumentation to customize your monitoring experience.
Top 3 links from last Issue
- Django and Postgres for the Busy Rails Developer by Andrew Atkinson
- TIL: Django relations are not cached in model instance by Enrique Soria
- CheckIN - All In One Software For Car Wash Companies.
Support
You can support this project by using one of the affiliate links below. These are always going to be projects I use and love! No "Bluehost" crap here!
- Buttondown - Email newsletter tool I use to send you this newsletter.
- Readwise - Best reading software company out there. I you want to up your e-reading game, this is definitely for you! It also so happens that I work for Readwise. Best company out there!
- Hetzner - IMHO the best place to buy a VPS or a server for your projects. I'll be doing a tutorial on how to use this in the future.
- SaaS Pegasus is one of the best (if not the best) ways to quickstart your Django Project. If you have a business idea but don't want to set up all the boring stuff (Auth, Payments, Workers, etc.) this is for you!
04 Feb 2025 8:30pm GMT
31 Jan 2025
Django community aggregator: Community blog posts
Django News - 400 DSF Members - Jan 31st 2025
News
PyPI Now Supports Project Archival
Projects on PyPI can now be marked as archived.
Django Software Foundation
400 individual members of the Django Software Foundation
The Django Software Foundation reached 400 individual members.
Updates to Django
Today 'Updates to Django' is presented by Abigail Afi Gbadago from Djangonaut Space!
Last week we had 21 pull requests merged into Django by 12 different contributors - including 2 first-time contributors! Congratulations to Gregory Mariani and Igor Scheller for having their first commits merged into Django - welcome on board!🎊
Highlights of the changes made:
- The
main
branch is now tracking development for Django 6.0. - You can now squash a squashed migration. This eases the squashing process (#19082).
- Support has been dropped for Python 3.10 & 3.11 (#19067)
Django Newsletter
Wagtail CMS
Our updated Accessibility Conformance Report
Wagtail has released a new Accessibility Conformance Report for version 6.3, showcasing improvements across WCAG 2.2 criteria, detailing compliance in the CMS, documentation, and websites, and inviting feedback for further accessibility enhancements.
Sponsored Link 1
Hiring Jr. Web Services Engineer
This position is for someone who can bring their python software development experience to support Playdate, Game Publishing, and our Apps! You would be responsible for contributing to and maintaining our growing flock of Flask and Django web applications.
Additionally, Panic hires interns every summer via The Script (https://thescript.org/internship-program/), designed for college students with underrepresented backgrounds entering freshman through senior years.
Articles
Database Indexing in Django
Explore the fundamentals of database indexing in Django-covering types, advantages, and practical examples-to help you significantly improve query performance and scalability in your projects.
An Introduction to Django Views
An overview of Django views, covering function-based vs. class-based approaches, best practices, and practical PyCharm tips for streamlined web development.
Django 5.2 simple_block_tag with HTMX
Django 5.2 introduces the new simple_block_tag()
, demonstrated here with HTMX to validate and test custom attributes for more robust and maintainable components.
Avoiding Mocks: Testing LLM Applications with LangChain in Django
A practical method for testing Django-based LLM apps with LangChain uses a custom fake backend to avoid mocks, enabling flexible refactoring and thorough validation of model interactions.
Add headings to HTML landmarks
Use visually hidden headings to make your website easier to navigate.
Rendering form fields as group in Django
A welcome addition in Django 5.0, the concept of field groups makes a lot easier to customize the layout of our Django forms.
Looking at Django task runners and queues
A look at different ways to combine scheduled and one-off background jobs in Django-comparing django-apscheduler, django-tasks, django-q2, Celery, and cron-to handle tasks like sending email and long-running processes efficiently.
Events
PyOhio 2025
PyOhio is a free annual Python community conference based in Ohio this July 26-27, 2025.
Tutorials
How to Use GraphQL in Django with Elasticsearch
A guide to combining Graphene-Django with Django Elasticsearch DSL to create high-performance GraphQL endpoints, complete with advanced search and filtering via Elasticsearch.
Sponsored Link 2
Django & Wagtail Hosting for just $9/month
New year, new site! Finally put those domain names to use and launch that side-project, blog, or personal site in 2025. Lock in this limited time pricing by Feb 28.
Podcasts
Real Python #236: Simon Willison: Using LLMs for Python Development
Simon talks about his LLM research and explores ways of writing Python code with these rapidly evolving tools.
Django News Jobs
⭐ Jr. Web Services Engineer at Panic 🆕 (featured)
Senior Backend Engineer at BactoBio 🆕
Senior Software Engineer at Spark
Front-end developer at cassandra.app
Lead Django Developer at cassandra.app
Développeur(se) back-end en CDI at Brief Media
Django Newsletter
Projects
drf-forms/drf-schema-adapter
Making using Django with frontend libraries and frameworks DRYer.
nanuxbe/django-classy-doc
django-classy-doc brings Classy Class-Based Views-style docs to your own code.
This RSS feed is published on https://django-news.com/. You can also subscribe via email.
31 Jan 2025 5:00pm GMT
Finishing Simple Signup - Building SaaS #213
In this episode, I completed the simplified sign up process for my JourneyInbox app. I finished off the final features that add account verification and initial engagement features to make sign up and nice and functional experience.
31 Jan 2025 6:00am GMT
29 Jan 2025
Django community aggregator: Community blog posts
Weeknotes (2025 week 05)
Weeknotes (2025 week 05)
Djangonaut Space
In December I wrote a few paragraphs about my decision to not run for the Django Steering Council, mentioning that I want to contribute in different ways.
I have offered to contribute to Djangonaut Space to do some mentoring. I'm already a bit stressed, but that's normal and to be expected. I'll probably have more to share about that in the close future!
Releases
- feincms-cookiecontrol 1.6: Removed the hardcoded dependency upon feincms3 and some additional code golfing. The cookie banner JavaScript is now back to <4KiB.
- django-curtains 0.7: Updated the CI job list and modernized the package somewhat, no code changes necessary. It's good to release updated versions though just to show that it's still actively maintained.
- django-prose-editor 0.10.3: Small CSS fixes and mainly updated TipTap/ProseMirror.
- django-imagefield 0.22: The updated version no longer autodeletes processed images; this wasn't really a problem before but I was a little bit fearful that images are still referenced elsewhere and this change let's me sleep better.
- feincms-oembed 2.0: Oembed support for FeinCMS 1 without actually depending upon the FeinCMS package itself. Still works.
- django-content-editor 7.2: The
Region
type is now hashable; this may be useful, or not. - feincms3 5.3.1: I undeprecated the
TemplateMixin
because even thoughPageTypeMixin
is nicer, sometimes all you need is a template selector.
29 Jan 2025 6:00pm GMT
28 Jan 2025
Django community aggregator: Community blog posts
Thinking About Risk: Sidebar #4: Quantitative Risk Revisited
In part 1 of this series, I briefly covered quantitive risk measuring - assigning a numeric value to risk, like "$3,500", rather than a qualitative label like "medium" - only to quickly recommend against trying it. In this final sidebar, I want to come back to this topic. I'll spend a bit more time explaining what I see as the pros and cons of quantitative risk measurement - why you might or might not want to use numeric values over more simple risk matrixes.
28 Jan 2025 6:00am GMT
27 Jan 2025
Django community aggregator: Community blog posts
Python Leiden (NL) meetup: python in applied mathematics - Tobias Datema
(One of my summaries of the first Python Leiden (NL) meetup in Leiden, NL).
Tobias studied applied mathematics at Delft University.
One of the fields he used python for was graph theory. A graph consists of points ("vertices") connected by lines ("edges"). It is a large field with many real world projects like social networks and logistics. He showed a demo he made with networkx, a python library that makes it real easy to do these kinds of graph calculations.
Graphs need to be shown. He used pyviz for that by converting the networkx graph to the format understood by pyviz.
Another field is machine learning. He did an experiment with a simulated self-driving car. He used a library that handles the basics like "reacting to a closed line on the road" and "measuring the distance to the dashed line on the road". The simulation is shown in a visual form, which makes it funny to look at.
In his study, python was also handy for statistics and numerical analysis.
27 Jan 2025 5:00am GMT
Python Leiden (NL) meetup: fawltydeps - Johan Herland
(One of my summaries of the Python Leiden (NL) meetup in Leiden, NL).
FawltyDeps is a python dependency checker. "Finding undeclared and unused dependencies in your notebooks and projects".
Note by Reinout: since 2009 I'm one of the maintainers of z3c.dependencychecker.... also a python dependency checker :-) So this talk interested me a lot, as I didn't know yet about fawltydeps.
A big problem in science is the "replication crisis". Lots of research cannot actually be reproduced when you try it... Data science is part of this problem. Reproducing your jupyter notebook for instance.
Someone looked at 22k+ jupyter notebooks. Only 70% had declared their dependencies, 46% could actually install the dependencies and only 5% actually could be run. ModuleNotFoundError and ImportError were the number 1 and 3 in the list of exceptions!
What is a dependency? For instance "numpy", if you have a import numpy as np in your file. Numpy isn't in the python standard library, you have to install it first.
You can specify dependencies in setup.py, pyproject.toml, requirements.txt and so. If you import something and don't specify it, it is an "undeclared dependency". When you later on remove an import and don't adjust your requirements.txt, you have an "unused dependency". That's not immediately fatal, but it might take up unnecessary space.
FawltyDeps was started to help with this problem: find undeclared and unused dependencies. It reports them. You can ask for a more detailed report with line numbers where the dependencies were found.
FawltyDeps supports most dependency declaration locations. requirements.txt, setup.py, pyproject, conda, etc. And it works with plain python files, notebooks, most python versions and most OSs. You can configure it on the commandline and in config files. There's even a handy command to add an example config to your pyproject.toml.
Handy: you can add it as a pre-commit hook (https://pre-commit.com). And: there's a ready-made github action for it, including good reporting.
Fawltydeps has to deal with several corner cases:
- Package names that don't match what you import. import sklearn and the dependency scikit-learn.
- Or setuptools that provides both setuptools and pkg_resources.
- For this it looks at various locations for installed packages to help figure out those mappings. It helps if you've installed FawltyDeps in your project's virtualenv.
- You can add your own custom mappings in your configuration to help FawltyDeps.
- You can exclude directories.
- There's a default list of "tool" packages that FawltyDeps doesn't complain about if you include them as dependency without importing them. Ruff, black, isort: those kinds of tools.
- Django projects can have dependencies that aren't actually imported. You can ignore those in the config to prevent them to be imported.
- At the moment, extra dependencies (like [test] or [dev] dependencies) are just handled as part of the whole set of dependencies.
27 Jan 2025 5:00am GMT
How to Use GraphQL in Django with Elasticsearch
When you need to use GraphQL with Django, a common practice is to use Graphene-Django, which allows you to query Django models. However, directly querying Django models might be too slow, especially when you have many complex relations. To speed that up, you can add one more layer of abstraction and index your Django models to an Elasticsearch server. In this article, I will show you how to create a GraphQL interface for querying posts from the Elasticsearch server.
Elasticsearch Server
The easiest way to install the Elasticsearch server locally is using EVM - Elasticsearch Version Manager:
$ sudo curl -o /usr/local/bin/evm https://raw.githubusercontent.com/duydo/evm/master/evm
$ sudo chmod +x /usr/local/bin/evm
Then you can install Elasticsearch 7.17.27 (or other version) with EVM, as follows:
$ evm install 7.17.27
By default, the Elasticsearch server will raise a warning if you don't have HTTPS or basic authentication. You can change one setting to turn off those warnings for localhost. To do so, add a line to ~/.evm/elasticsearch-7.17.27/config/elasticsearch.yml
:
xpack.security.enabled: false
Now, you can start the server with:
$ evm start
If you need more Elasticsearch versions on the same computer, you can easily install and switch between them.
Python Packages
Install the latest packages of Django Elasticsearch DSL for connecting to Elasticsearch server, and Graphene-Django for GraphQL implementation:
(venv)$ pip install Django
(venv)$ pip install django-elasticsearch-dsl
(venv)$ pip install graphene-django
Django Settings
Add the installed apps to INSTALLED_APPS
in the myproject/settings.py. Also, add a few more settings that we will need in this exercise:
INSTALLED_APPS = [
# Contributed Django apps
# ...
# Third-party apps
"django_elasticsearch_dsl",
"graphene_django",
# Local apps
"posts",
]
PROJECT_NAME = "myproject"
ENVIRONMENT = "dev"
ELASTICSEARCH_DSL = {
"default": {
"hosts": "http://localhost:9200",
}
}
GRAPHENE = {
"SCHEMA": "elasticsearch_graphql.schema.schema",
}
Models and Administration for the Posts App
Let's create a posts app with two models: Category
and Post
:
The posts/models.py file will look like this:
from django.db import models
class Category(models.Model):
title = models.CharField("Title", max_length=255)
slug = models.SlugField("Slug", max_length=255)
class Meta:
verbose_name = "Category"
verbose_name_plural = "Categories"
ordering = ["title"]
def __str__(self):
return self.title
class Post(models.Model):
title = models.CharField("Title", max_length=255)
slug = models.SlugField("Slug", max_length=255)
content = models.TextField("Content")
categories = models.ManyToManyField(Category)
class Meta:
verbose_name = "Post"
verbose_name_plural = "Posts"
ordering = ["title"]
def __str__(self):
return self.title
Also let's create administration posts/admin.py to be able to add some entries easily:
from django.contrib import admin
from .models import Category, Post
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
list_display = ["title", "slug"]
prepopulated_fields = {"slug": ["title"]}
@admin.register(Post)
class Post(admin.ModelAdmin):
list_display = ["title", "slug"]
list_filter = ["categories"]
filter_horizontal = ["categories"]
prepopulated_fields = {"slug": ["title"]}
Create the database schema and the superuser, then run the local development server with the following Django management commands:
(venv)$ python makemigrations
(venv)$ python migrate
(venv)$ python createsuperuser
(venv)$ python runserver
Add some posts and categories in the administration:
http://localhost:8000/admin/
Elasticsearch Documents for the Posts
Let's create PostDocument
definition for the Elasticsearch index of the Post
model and its categories at posts/documents.py:
import graphene
from django.conf import settings
from django_elasticsearch_dsl import Document
from django_elasticsearch_dsl.registries import registry
from django_elasticsearch_dsl import fields
from .models import Post
@registry.register_document
class PostDocument(Document):
title = fields.TextField()
slug = fields.KeywordField()
content = fields.TextField()
categories = fields.NestedField(
properties={
"title": fields.TextField(),
"slug": fields.KeywordField(),
}
)
class Index:
name = f"{settings.PROJECT_NAME}_{settings.ENVIRONMENT}_posts"
settings = {"number_of_shards": 1, "number_of_replicas": 0}
class Django:
model = Post
ignore_signals = False
auto_refresh = True
queryset_pagination = 5000
def prepare(self, instance):
data = super().prepare(instance)
# Prepare categories field
data["categories"] = [
{
"title": category.title,
"slug": category.slug,
}
for category in instance.categories.all()
]
return data
To index the posts on the Elasticsearch server, run the following:
(venv)$ python manage.py search_index --rebuild
Let's see if the entries were indexed and can be retrieved.
At first, run the Django shell:
(venv)$ python manage.py shell
Then try to list out items from the Elasticsearch index:
>>> from posts.documents import PostDocument
>>> for doc in PostDocument.search():
... print(doc.title)
It will list up to 10 posts (that's the default pagination) from the index:
Creating AI-based Summaries in a Django Website
Creating Open Graph Images in Django for Improved Social Media Sharing
HTTPS for Django Development Environment
GraphQL Types and Queries for the Posts App
Now, create the GraphQL schema posts/schema.py for the categories and posts, as follows:
import operator
from functools import reduce
import graphene
from .documents import PostDocument
class ElasticsearchObjectType(graphene.ObjectType):
@classmethod
def from_elasticsearch(cls, elasticsearch_document):
instance = cls()
instance.elasticsearch_document = elasticsearch_document
return instance
class ElasticsearchCategoryType(ElasticsearchObjectType):
title = graphene.String()
slug = graphene.String()
def resolve_title(self, info):
return self.elasticsearch_document.title
def resolve_slug(self, info):
return self.elasticsearch_document.slug
class ElasticsearchPostType(ElasticsearchObjectType):
title = graphene.String()
slug = graphene.String()
content = graphene.String()
categories = graphene.List(of_type=ElasticsearchCategoryType)
def resolve_title(self, info):
return self.elasticsearch_document.title
def resolve_slug(self, info):
return self.elasticsearch_document.slug
def resolve_content(self, info):
return self.elasticsearch_document.content
def resolve_categories(self, info):
return [
ElasticsearchCategoryType.from_elasticsearch(
elasticsearch_document=category
)
for category in self.elasticsearch_document.categories or []
]
class Query(object):
elasticsearch_posts = graphene.List(
ElasticsearchPostType,
limit=graphene.Int(),
offset=graphene.Int(),
search=graphene.String(),
categories=graphene.List(of_type=graphene.String),
)
def resolve_elasticsearch_posts(
self,
info,
limit=10,
offset=0,
search=None,
categories=None,
):
from elasticsearch_dsl.search import Q
search_obj = PostDocument.search()
queries = []
if search:
queries.append(
Q(
"multi_match",
query=search,
fields=[
"title^5",
"slug^4",
"content^3",
],
type="best_fields",
tie_breaker=0.3,
fuzziness="AUTO",
fuzzy_transpositions=True,
lenient=True,
)
)
if categories:
queries.append(
Q(
"nested",
path="categories",
query=Q("terms", categories__slug=categories),
)
)
if queries:
# All filters AND-ed
search_obj = search_obj.query(reduce(operator.iand, queries))
search_obj = search_obj[offset : offset + limit if limit else None]
return [
ElasticsearchPostType.from_elasticsearch(elasticsearch_document=result)
for result in search_obj.execute()
]
Here, we have an ElasticsearchObjectType
that provides a custom method from_elasticsearch
to initiate GraphQL objects from Elasticsearch instead of Django models.
The query for elasticsearch_posts
has two filters: by a search string and by a list of OR-ed category slugs. The search query looks into title
, slug
, and content
fields with different boosting weights and searches for the best match. The fuzziness set to "AUTO"
allows mistakes in the search string by two letters.
At the project level, create Graphene Relay - a schema class that uses a Query class inheriting from all the Query classes from all Django apps. The file can be located at myproject/schema.py and have this content:
import graphene
import posts.schema
class Query(posts.schema.Query, graphene.ObjectType):
pass
schema = graphene.Schema(query=Query)
Finally, enable the GraphQL endpoint in the myproject/urls.py:
from django.contrib import admin
from django.urls import path
from django.views.decorators.csrf import csrf_exempt
from graphene_django.views import GraphQLView
urlpatterns = [
path("graphql/", csrf_exempt(GraphQLView.as_view(graphiql=True))),
path("admin/", admin.site.urls),
]
Checking the GraphQL Queries
Navigate to http://localhost:8000/graphql/
Graphene-Django comes with a GraphiQL user interface, which, when accessed from a browser, allows the user to query GraphQL and see results in the same window:
A search query for "AI" with categories "Intermediate" or "Advanced" can look like:
query FilteredPosts {
elasticsearchPosts(
search: "AI"
categories: ["intermediate", "advanced"],
limit: 10,
offset: 0,
) {
title
slug
categories {
title
slug
}
}
}
It will produce results in JSON just like this:
{
"data": {
"elasticsearchPosts": [
{
"title": "Creating AI-based Summaries in a Django Website",
"slug": "creating-ai-based-summaries-in-a-django-website",
"categories": [
{
"title": "Basics",
"slug": "basics"
},
{
"title": "Django",
"slug": "django"
},
{
"title": "Gemini",
"slug": "gemini"
},
{
"title": "Intermediate",
"slug": "intermediate"
},
{
"title": "Large Language Models",
"slug": "large-language-models"
},
{
"title": "PyBazaar",
"slug": "pybazaar"
},
{
"title": "Simplemind",
"slug": "simplemind"
}
]
},
{
"title": "HTTPS for Django Development Environment",
"slug": "https-for-django-development-environment",
"categories": [
{
"title": "DevOps",
"slug": "devops"
},
{
"title": "Development",
"slug": "development"
},
{
"title": "Django",
"slug": "django"
},
{
"title": "HTTPS",
"slug": "https"
},
{
"title": "Intermediate",
"slug": "intermediate"
},
{
"title": "SSL",
"slug": "ssl"
},
{
"title": "TLS",
"slug": "tls"
}
]
}
]
}
}
Conclusion
Using Elasticsearch with GraphQL is not trivial, but it provides excellent performance, especially for complex data structures. The best way to implement that in Django that I know of is combining Django Elasticsearch DSL and Graphene-Django.
Cover photo Angela Roma
27 Jan 2025 4:40am GMT
25 Jan 2025
Django community aggregator: Community blog posts
Looking at Django task runners and queues
I use django-apscheduler to run a queue of scheduled tasks. Now I also need the ability to run one-off tasks and that turned out to not be so simple.
25 Jan 2025 5:59am GMT
24 Jan 2025
Django community aggregator: Community blog posts
Django News - Django 5.2 alpha 1 release - Jan 24th 2025
News
Django 5.2 alpha 1 released
Django 5.2 alpha 1 is now available. It represents the first stage in the 5.2 release cycle and is an opportunity for you to try out the changes coming in Django 5.2.
Hello from the new Steering Council; and a quick temporary voting process change
The Steering Council is officially in action, and we want to give you a heads-up on a change we're making for the short term.
Djangonaut Space - New session 2025
Djangonaut Space is holding a fourth session! This session will start on February 17th, 2025. Applications are open until January 29th, 2025, Anywhere on Earth.
Tailwind CSS v4.0 - Tailwind CSS
Tailwind CSS v4.0 is out - an all-new version of the framework optimized for performance and flexibility, with a reimagined configuration and customization experience, and taking full advantage of the latest advancements the web offers.
Django Software Foundation
President of the Django Software Foundation
Notes from the Thibaud Colas, the new President of the Django Software Foundation.
Updates to Django
Today 'Updates to Django' is presented by Velda Kiara from Djangonaut Space!
Last week we had 26 pull requests merged into Django by 10 different contributors - including 1 first-time contributor! Congratulations to Thibaut Decombe for having their first commits merged into Django - welcome on board 🎊!
Big news! Django 5.2a1 is released! Please test the alpha version, try out the new features, and report any regressions on Trac.
The following enhancements were added to Django 5.2 last week:
- Built-in aggregate functions accepting only one argument (
Avg
,Count
, etc.) now raise aTypeError
when called with an incorrect number of arguments. - The ability to override the
BoundField
class for fields, forms, and renderers, providing greater flexibility in form handling.
Django Newsletter
Wagtail CMS
Results of the 2024 Wagtail headless survey
The results of the 2024 Wagtail headless survey are here! There are plenty of expected results plus a few surprises.
Sponsored Link 1
Django & Wagtail Hosting for just $9/month
New year, new site! Finally put those domain names to use and launch that side-project, blog, or personal site in 2025. Lock in this limited time pricing by Feb 28.
Articles
Ideas how to support Tailwind CSS 4.x in django-tailwind-cli
A look at potential updates to align with Tailwind's new CSS-first configuration, simplified theme setup, and other breaking changes, while weighing user-friendly migration strategies versus manual transitions.
Monkeypatching Django
A deep dive into how the nanodjango project leverages monkeypatching and metaclass manipulation to enable full Django functionality within a single-file application, bridging the gap between lightweight prototypes and Django's powerful features.
Django Islands: Part 1 - Side Quests by Bo Lopker
On using SolidJS with Django to build a type-safe frontend that the whole team will love.
Show Django forms inside a modal using HTMX
Learn how to create and edit models using Django forms inside a modal using HTMX
Exploring Python Requirements
A guide to using the uv tool for managing Python project dependencies, showcasing features like tree views, listing outdated packages, and integrating interactive package selection with tools like wheat to streamline dependency updates.
Django admin tip: Adding links to related objects in change forms
This article explores two practical methods for enhancing the Django admin interface by linking related objects directly in change forms, improving navigation and usability.
Django Developer Salary Report 2025
An annual report from Foxley Talent on Django developer salaries.
urllib3 in 2024
Highlights from 2024 for the urllib3 team in terms of funding, features, and looking forward.
Tutorials
The definitive guide to using Django with SQLite in production
A comprehensive look at using SQLite for Django projects under real-world traffic, detailing its benefits and potential challenges and deployment strategies.
Sponsored Link 2
Buff your Monolith
Scout Monitoring delivers performance metrics, detailed traces and query stats for all your app routes with a five-minute setup. Add our Log Management and have everything you need to make your Django app shiny and fast. Get started for free at https://try.scoutapm.com/djangonews
Podcasts
Django Chat #174: Beyond Golden Pathways - Teaching Django with Sheena O'Connell
Sheena is a long-time Django developer and teacher currently focused on Prelude Tech, small workshops focused on topics like Django, HTMX, and Git.
Django News Jobs
Senior Backend Engineer at BactoBio 🆕
Senior Software Engineer at Spark
Front-end developer at cassandra.app
Lead Django Developer at cassandra.app
Développeur(se) back-end en CDI at Brief Media
Django Newsletter
Django Forum
Call for Project Ideas and Prospective Mentors for GSoC 2025
Google Summer of Code (GSoC) rolls around again. Historically this has been a real boon for Django, with successes again this year. We need project ideas and prospective mentors for 2025. Do you have one? Is that you?
Projects
Salaah01/django-action-triggers
A Django library for asynchronously triggering actions in response to database changes. It supports integration with webhooks, message brokers (e.g., Kafka, RabbitMQ), and can trigger other processes, including AWS Lambda functions.
OmenApps/django-templated-email-md
An extension for django-templated-email for creating emails with Markdown.
This RSS feed is published on https://django-news.com/. You can also subscribe via email.
24 Jan 2025 5:00pm GMT
23 Jan 2025
Django community aggregator: Community blog posts
Strip spaces
When I joined TriOptima back in 2010, a common pattern emerged where names of things were slightly off because of stray whitespaces. Sometimes we had duplicates like "foo"
, "foo "
and " foo"
in the database. Sometimes we couldn't find stuff in logs because you searched for "foo was deleted"
, when actually you had to search for "foo was deleted"
(notice the double space!). Sorting was "broken" because " foo"
and "foobar"
are not next to each other. And more issues that I can't remember…
It was everywhere, causing problems across the entire code base. Each individual issue was easily fixed by cleaning up the data, but it added up to an annoying support burden. My fix at the time was to make a function that took a Django Form
instance and returned a new instance with space stripping on all fields. Something like:
form = auto_strip(Form(...))
After I added that to every single Django form in the entire code base that slow and steady trickle of bugs and annoyances just stopped. From seeing a few a month consistently to zero for the next ~9 years. Even better: I never got a complaint about it.
This was fixed in Django 1.9 after some fierce debating back and forth ("will never happen" was uttered). In iommi forms we've had this since the beginning, which turns out to be a few months ahead of when Django took this decision (although it was tri.form and not iommi back then).
Just when you think you're out
Unfortunately the story doesn't end here. I started getting this issue again, and it took me a while to realize it's because of SPA-like pages that uses Pydantic serializers instead of a form library. To solve this I added this base class for my schemas:
class Schema(ninja.Schema):
@validator('*')
def strip_spaces(cls, v: Any) -> Any:
if isinstance(v, str) and '\n' not in v:
return v.strip(' ')
return v
The reason I'm not stripping spaces if the text contains a newline is to avoid situations where you have multiline text fields with indented code. Maybe it's just programmers who will care, but we tend to care a lot :P
Modifying data silently and by default like this sounds like a bad idea and I also get a little pit in my stomach when I think about it with that frame of mind, but this specific case seems like all win and no downside from my 14 years of experience doing it.
23 Jan 2025 6:00am GMT
22 Jan 2025
Django community aggregator: Community blog posts
Beyond Golden Pathways - Teaching Django with Sheena O’Connell
- Sheena's Personal Site
- Prelude
- Guild of Educators
- DjangoCon US Keynote - Power to the People who Teach the People
- PyCon Italia Keynote - A Tale from the Trenches
- Escape conf - Testing Python Web Apps using Playwright
- Webinar: Why HTMX makes good business sense
- Using Cursor to Port Django tests to pytest
Sponsor
This episode was brought to you by Buttondown, the easiest way to start, send, and grow your email newsletter. New customers can save 50% off their first year with Buttondown using the coupon code DJANGO.
22 Jan 2025 6:00pm GMT
17 Jan 2025
Django community aggregator: Community blog posts
Django admin tip: Adding links to related objects in change forms
Django admin tip: Adding links to related objects in change forms
Any issue which came up on the Django Forum and Discord is how to add links to other objects to the Django administration interface. It's something I'm doing often and I want to share the pattern I'm using.
It's definitely not rocket science and there are probably better ways to do it, but this one works well for me.
Method 1: Override the change form template
In one project users can be the editor of exactly one organization. The link between organizations and users is achieved using a Editor
model with a ForeignKey(Organization)
and a OneToOneField(User)
.
I wanted to add a link to the organization page at the bottom of the user form. An easy way to achieve this is to add a template at templates/admin/auth/user/change_form.html
(or something similar if you're using a custom user model):
{% extends "admin/change_form.html" %}
{% block after_related_objects %}
{{ block.super }}
{% if original.editor %}
<fieldset class="module aligned">
<h2>Organization</h2>
<div class="form-row">
<a href="{% url 'admin:organizations_organization_change' original.editor.organization.pk %}">{{ original.editor.organization }}</a>
</div>
</fieldset>
{% endif %}
{% endblock after_related_objects %}
The original
context variable contains the object being edited. The editor
attribute is the reverse accessor for the OneToOneField
mentioned above.
Method 2: Add a method to the model admin class returning a HTML blob
A terrible but also nice way is to add a method to the ModelAdmin
class which returns the HTML containing the links you want, and adding the name of the method to readonly_fields
. This is even mentioned in the official readonly_fields
documentation but I discovered this by accident a few years back.
The method name doesn't have to be added anywhere else, not to fields
nor do you have to define fieldsets
for this to work. Just adding it to readonly_fields
appends it to the end of the form, before any eventual inlines you're using.
from django.template.loader import render_to_string
from app import models
@admin.register(models.Class)
class ClassAdmin(admin.ModelAdmin):
list_display = ["name", "language_code"]
readonly_fields = ["admin_show_custom_districts"]
@admin.display(description=_("districts")
def admin_show_custom_districts(self, obj):
return render_to_string(
"admin/admin_show_custom_districts.html",
{"custom_districts": obj.customdistrict_set.all()},
)
17 Jan 2025 6:00pm GMT
Django News - Django 5.1.5 security release - Jan 17th 2025
News
Django security releases issued: 5.1.5, 5.0.11, and 4.2.18
Several new security updates. As ever, you should endeavor to be on the latest version of Django for security reasons.
Django 5.2 alpha 1 released
Django 5.2 alpha 1 is now available. It represents the first stage in the 5.2 release cycle and is an opportunity for you to try out the changes coming in Django 5.2.
Python Insider: Python 3.14.0 alpha 4 is out
Python 3.14 is still in development. This release, 3.14.0a4, is the fourth of seven planned alpha releases.
Djangonaut Space Session 4 Applications Open!
Djangonaut Space Applications are open now and close on January 29th, 2025 AOE.
Django Software Foundation
Hello from the new Steering Council; and a quick temporary voting process change
An update on the voting process to move faster on the smaller things the SC currently has in from of them.
Updates to Django
Today 'Updates to Django' is presented by Velda Kiara from Djangonaut Space!
Last week we had 20 pull requests merged into Django by 12 different contributors 🎊!
Highlights of the changes made:
- The
contrib.postgres
aggregatesordering
argument has been deprecated in favor oforder_by
. URLField
values are now rendered as links in the Django admin.- A new
JSONArray
function has been added todjango.db.models.functions
, allowing users to construct JSON arrays. This function operates similarly to the existingJSONObject
function. - The Django shell has been updated to auto-import models from your app. This enhancement allows users to subclass the shell for customized behavior and import additional elements. This contribution was from Salvo Polizzi a contributor from Google Summer of Code, thank you for your contribution to Django 🎉!
Want to see what Djangonauts have been up to? Check out this PR review session
Django Newsletter
Articles
Testing your Python package releases
On discovering that the release process for the Django Debug Toolbar wasn't as robust as thought.
Catching memory leaks with your test suite
If you have a good test suite, you may be able use pytest fixtures to identify memory and other resource leaks.
Truncating timedeltas in Django
How to efficiently aggregate event counts over time relative to a post's creation in Django by using database annotations.
How to check if a Django template has been overridden
A quick way to check if a template has been overridden. Especially useful for Django package authors.
Speed up CI with uv
Use uv
to make linting and testing on GitHub Actions around 1.5 times as fast.
Django: render JavaScript import maps in templates
How to integrate JavaScript import maps into Django templates using a custom template tag to generate module import paths dynamically.
State of the Server 2025
An in-depth review of the author's self-hosted server setup, covering hardware, storage, backup strategies, self-hosted applications, security improvements, and future plans for optimization and privacy enhancements.
Sponsored Link 2
Buff your Monolith
Scout Monitoring delivers performance metrics, detailed traces and query stats for all your app routes with a five-minute setup. Add our Log Management and have everything you need to make your Django app shiny and fast. Get started for free at https://try.scoutapm.com/djangonews
Django News Jobs
Software Engineer I at Spark 🆕
Senior Software Engineer at Spark 🆕
Engineering Manager at Spark 🆕
Front-end developer at cassandra.app
Lead Django Developer at cassandra.app
Développeur(se) back-end en CDI at Brief Media
Full-stack Python Developer at Scalable Path
Django Newsletter
Projects
torchbox/wagtail-wordpress-import
A package for Wagtail CMS to import WordPress blog content from an XML file into Wagtail.
miketheman/pytest-max-warnings
A Pytest plugin to exit non-zero exit code when the configured maximum warnings has been exceeded.
This RSS feed is published on https://django-news.com/. You can also subscribe via email.
17 Jan 2025 5:00pm GMT
Signin Email - Building SaaS #212.1
In this episode, we continued on the sign up workflow simplification. The focus of this stream was on adding the background task that will send the magic link email to allow sign in.
17 Jan 2025 6:00am GMT
Building SaaS with Python and Django #212.2
In this episode, we continued on the sign up workflow simplification. The focus of this stream was on adding the background task that will send the magic link email to allow sign in. This is the second half of the stream because my internet cut out.
17 Jan 2025 6:00am GMT