Sign in

adamghill

@adamghill.com
1.5K followers 774 following 698 posts

I write (Python|JavaScript|HTML|CSS) and sometimes it's useful. 🛠️ github.com/adamghill 💥 adamghill.com 🧠 1/2 of djangostickers.com and djangobrew.com ✈️ / 📍🪩 / 👻 / ☕️ / 🎥

PostsRepliesMedia
adamghill @adamghill.com · 03/09/2026
"This project helped me rediscover the purest joy of coding: using the technology I possess to solve a real problem for the people around me, making everyone's life a little easier and a little happier.” happytoyscout.com/en/reports/h... #godzilla
Hello Kitty X Godzilla collaboration toy
040
adamghill @adamghill.com · 29/08/2026
Instead of To Live and Die in LA, I watched Hell Comes to Frogtown, and I might have made a terrible mistake?
110
adamghill @adamghill.com · 19/07/2026
Released 0.27.0 of dj-angles, a library to transpile #HTML into regular #Django templates. - django-compressor integration - dj-value attribute to render Django variables as an element’s inner content 📖 dj-angles-adamghill.com
<!-- django-compressor.html -->
<dj-compress css> <!-- {% compress css %} -->
  <style>.critical { color: red; }</style>
</dj-compress> <!-- {% endcompress %} --><!-- value-attribute.html -->
<div dj-value="request.user">  <!-- <div>{{ request.user }}</div> -->
</div>
000
adamghill @adamghill.com · 07/12/2025
0.6.1 of django-new has been released. 🚀 - Lots of UI tweaks. - `--data` flag. - Generate `summary.html` for a user-friendly explanation. - BETA: `--install` to install packages. 🛠️ github.com/adamghill/django-new 📦 pypi.org/project/django-new/
040
adamghill @adamghill.com · 10/11/2025
@universalorl.bsky.social @universalstudiosfl.bsky.social Check out this actual stained glass panel based on the piece in the Tribute store above the registers at HHN 34 in Orlando. 😍 There are over 800 pieces of glass and 15 different colors and it took 2.5 weeks of working around 2-8 hours/day!
Full panelTop part of the panelBottom part of the panelPanel in progress
060
adamghill @adamghill.com · 09/11/2025
My wife creates a lot of #stainedglass projects that are a little outside the norm. 👻 Here is one she made before #Halloween to pay homage to Stanley Kubrick's classic #film, The Shining. 🤩 glass-o-lantern.com/the-shining/ 🎃 www.instagram.com/glass_o_lant... #cinema #letterboxd #horror #art
Stained glass panel of the Grady Sisters from The Shining, standing on the iconic orange and red patterned carpet. The background is clear glass with red streaks, as if from blood.
1112
adamghill @adamghill.com · 23/10/2025
New package alert: dj-spinners 🚨 Pure SVG loading spinners for #Django. ``` {% load dj_spinners %} {% spinner '90-ring' %} ``` 🛠️ github.com/adamghill/dj... 📦 pypi.org/project/dj-s...
131
adamghill @adamghill.com · 19/09/2025
I packed up 20 sticker packs (designed by @sjbitcode.bsky.social!) the other day and mailed them halfway across the world. 💚 Hoping people like them and that we can help do our small part in celebrating the #Django 20th birthday in as many places as possible! 🎂
4 piles of Django pony stickers.Piles of sticker packs.A big spread of Django pong stickers.
161
adamghill @adamghill.com · 17/09/2025
@sjbitcode.bsky.social and I are working on beesocial.dev, a site where techies can show off all the things they work on, follow others, and get inspiration. 🐝 We are giving away a special t-shirt (ex. www.redbubble.com/people/sjbit...) to one lucky winner who signs up and submits feedback to us. ✨
Slide with QR code of BeeSocial and an arrow pointing at the Give Feedback in the navigation.Homepage of beesocial.dev.Example profile for beesocial.dev.
021
adamghill @adamghill.com · 13/09/2025
Released 0.1.1 of `troml`, a tool that suggests classifiers, i.e. pypi.org/classifiers/, for #Python packages. It looks at `project.python-requires` and dependencies in `pyproject.toml`, and for a `py.typed` file. ⚙️ github.com/adamghill/tr... 📦 pypi.org/project/troml/
❯ uvx troml
Installed 11 packages in 12ms
Loading data from '.'
 - Add typed classifier based on py.typed file
 - Remove legacy license classifier (https://peps.python.org/pep-0639/#deprecate-license-classifiers)
 - Python requirement: >=3.9.7
 - Add 8 classifiers for Python
 - Add 5 classifiers for Django

Current classifiers TOML
classifiers = [
  "Development Status :: 4 - Beta",
  "License :: OSI Approved :: MIT License",
]

Suggested classifiers TOML
classifiers = [
  "Development Status :: 4 - Beta",
  "Framework :: Django",
  "Framework :: Django :: 5.1",
  "Framework :: Django :: 5.2",
  "Framework :: Django :: 6",
  "Framework :: Django :: 6.0",
  "Programming Language :: Python",
  "Programming Language :: Python :: 3.10",
  "Programming Language :: Python :: 3.11",
  "Programming Language :: Python :: 3.12",
  "Programming Language :: Python :: 3.13",
  "Programming Language :: Python :: 3.14",
  "Programming Language :: Python :: 3.15",
  "Programming Language :: Python :: 3.9",
  "Typing :: Typed",
]
073
adamghill @adamghill.com · 11/09/2025
Rilo Kiley was flipping amazing!
110
adamghill @adamghill.com · 09/09/2025
Released v0.4.0 of dj-toml-settings ⚙️ - Added `$value` to specify a literal value. - Added `$type` to allow casting values to a particular type. Currently supported types: bool, int, str, float, decimal, datetime, date, time, timedelta, url. 🛠️ github.com/adamghill/dj... 📦 pypi.org/project/dj-t...
Example TOML file for Django settings. Includes a highlighted section:

```
# Values can be casted to a bool, int, str, float, decimal, datetime, date, time, timedelta, url
SITE_ID = { "$value" = "1", "$type" = "int" }
```

Which is the new functionality.
031
adamghill @adamghill.com · 09/09/2025
Now we are cooking with gas
Screenshot of saved posts announcement.
010
adamghill @adamghill.com · 07/09/2025
I will be at #DjangoConUS September 8-9 in Chicago. In case this sparks some ideas, here are some things I’ve been thinking about recently: - #Django deployments - #SQLite in production - bootstrapping - Django marketing - djp.readthedocs.io Come find me to chat about these things (or anything)!
The Django Pony as a DJ scratching records. Designed by https://beesocial.dev/@sjbitcode.
051
adamghill @adamghill.com · 05/09/2025
Yay! This piece was inspired by our recent trip to Japan — highly recommended if you are into kaiju and are able to make it over there!
Me running away from a giant Godzilla in the Godzilla store located in Odaiba, Tokyo.
100
adamghill @adamghill.com · 05/09/2025
My wife has been creating a ton of custom stained glass pieces recently and this #Godzilla is amazing. I love the fire everywhere, atomic breath, and the textured glass for its body. #art #stainedglass #movies #artist #filmsky #Letterboxd #japan #cinema #horror
Stained glass of Godzilla with buildings and fire in the background. Godzilla has atomic breath and textured glass for its body.
54710
adamghill @adamghill.com · 01/09/2025
Come on, producers
So many movies named “house”
030
adamghill @adamghill.com · 01/09/2025
Published 0.3.0 and 0.3.1 of `dj-toml-settings` ⚙️ - Handle `datetime`, `int`, `float`, `list`, `dict`, `datetime`, and `Callable` as variables. - Handle appending to a variable for `Path`. - Add `$none` special operator. 🛠️ github.com/adamghill/dj... 📦 pypi.org/project/dj-t... #Django #TOML
[tool.django]

# Paths are relative to the TOML file (unless they are absolute)
BASE_DIR = { "$path" = "." }
STATIC_ROOT = { "$path" = "staticfiles" }

# This sets the key based on the environment variable
SECRET_KEY = { "$env" = "SECRET_KEY" }

# This sets the key based on the environment variable, but has a fallback
ADMIN_URL_PATH = { "$env" = "ADMIN_URL_PATH", "$default"="admin" }

# Booleans, arrays, tables (dictionaries), integers, strings, floats, dates are all supported in TOML
DEBUG = true
ALLOWED_HOSTS = [
  "127.0.0.1",
]

# This is an implicit dictionary and equivalent to `COLTRANE = { TITLE = "Example blog" }`
[tool.django.COLTRANE]
TITLE = "Example blog"

# Any name can be used under `apps` for organizational purposes
[tool.django.apps.tailwind-cli]
TAILWIND_CLI_USE_DAISY_UI = true
TAILWIND_CLI_SRC_CSS = ".django_tailwind_cli/source.css"

# These settings are included when the `ENVIRONMENT` environment variable is "development"
[tool.django.envs.development]
ALLOWED_HOSTS = { "$insert" = "example.localhost" }

# These settings are included when the `ENVIRONMENT` environment variable is "production"
[tool.django.envs.production]
DEBUG = false
ALLOWED_HOSTS = { "$insert" = "example.com" }
020
adamghill @adamghill.com · 28/08/2025
Just published 0.2.0 of dj-toml-settings! ⚙️ It provides the ability to load #Django settings from a #TOML file. Changelog: - Updated readme with (hopefully) clearer examples - Better support for path variables 🛠️ github.com/adamghill/dj... 📦 pypi.org/project/dj-t...
[tool.django]
BASE_DIR = { path = "." }
SECRET_KEY = { env = "SECRET_KEY" }
ADMIN_URL_PATH = { env = "ADMIN_URL_PATH", default="admin" }
DEBUG = true
ALLOWED_HOSTS = [
  "127.0.0.1",
]

# Implicit dictionaries are supported
# This is equivalent to `COLTRANE = { TITLE = "Example blog" }`
[tool.django.COLTRANE]
TITLE = "Example blog"

# Any app name can be used for organizational purposes
[tool.django.apps.tailwind-cli]
TAILWIND_CLI_USE_DAISY_UI = true
TAILWIND_CLI_SRC_CSS = ".django_tailwind_cli/source.css"

# These settings are included when `ENVIRONMENT` environment variable is "development"
[tool.django.envs.development]
DEBUG = false
ALLOWED_HOSTS = [
  "example.localhost",
]

# These settings are included when `ENVIRONMENT` environment variable is "production"
[tool.django.envs.production]
DEBUG = false
ALLOWED_HOSTS = { insert = "example.com" }
000
adamghill @adamghill.com · 23/08/2025
🚀 New #Django library: dj-raincheck ☔️ Quickly schedule functions to run after a view request is completed without setting up any complicated background task infrastructure. ⚙️ github.com/adamghill/dj... 📦 pypi.org/project/dj-r...
# views.py
from django.core.mail import send_mail
from dj_raincheck import raincheck

@raincheck
def send_email(to: str, subject: str, body: str) -> None:
    send_mail(subject, body, 'me@example.com', [to])


def index(request):
    # This will schedule the `send_email` function to run
    # after the current request has completed
    send_email.schedule('customer@example.com', 'Confirm Signup', body)

    return render(request, "index.html")
070
adamghill @adamghill.com · 10/08/2025
Light shining through window onto a stage with suitcases.
010
adamghill @adamghill.com · 05/08/2025
The HTML formatter kept breaking up a long `{% include … %}` tag and turns out DTL doesn't like new lines. 🥲 Thank goodness `<dj-include>` works as expected.
Two examples of including a partial. First is DTL with {% include %} which is too long so the new line breaks. The second is dj-include with handles the newline.
020
adamghill @adamghill.com · 03/08/2025
Gringotts Bank with a dragon on top
120
adamghill @adamghill.com · 29/07/2025
Python has something similar, but honestly… way less compelling and a little sanitized imo.
Python's community is vast; diverse & aims to grow;
Python is Open.

Great software is supported by great people, and Python is no exception. Our user base is enthusiastic and dedicated to spreading use of the language far and wide. Our community can help support the beginner, the expert, and adds to the ever-increasing open-source knowledgebase.
000
adamghill @adamghill.com · 29/07/2025
Declarations like this make me want to try out Gleam. Plus, it just looks like fun.
As a community, we want to be friendly too. People from around the world, of all backgrounds, genders, and experience levels are welcome and respected equally. See our community code of conduct for more.

Black lives matter. Trans rights are human rights. No nazi bullsh*t.
110
adamghill @adamghill.com · 29/07/2025
Each profile on beesocial.dev now has a QR code next to the username for easier sharing at in-person events. Tap it to open a modal with a bigger QR code just in case. 🚀
020
adamghill @adamghill.com · 24/07/2025
Finally cleaned up these default images for links without a favicon. Reminder to self: need to add favicons for most of my side projects. 😂
Messy favicons.Delightful favicons.
000
adamghill @adamghill.com · 22/06/2025
We think social platforms can be a force for community-building and collaboration, so we wrote a manifesto for BeeSocial. beesocial.dev/manifesto Help us build something better by signing up and giving us feedback! We'd love to hear what you think and what could be improved. ✨
As techies, we understand how systems work -- and how they can be misused. Social media platforms are some of the most complex, data-rich systems ever built, but they’re optimized for one thing above all: engagement. Not value, not clarity, not real connection. Just attention.

That means the loudest, most emotionally triggering content wins.

Rage-clicking, algorithmic dogpiling, and performative posting aren’t side effects. They are design outcomes.

It's not about signal, it's about stimulus.
021
adamghill @adamghill.com · 21/06/2025
Colophon for beesocial.dev for anyone interested: beesocial.dev/colophon. No vibe coding, just good vibes. #Django #Tailwind #TailwindCSS #HTMX #SQLite #Python
Colophon for beesocial.dev: Django, Coltrane, dj-angles, Daisy UI, Tailwind, HTMX, Devicon, Coolify, SQLite, Litestream.
130
adamghill @adamghill.com · 21/06/2025
We have some (read: lots! bordering on too many) ideas for other features, but would love to hear any early feedback. Want to see an example of what a profile looks like? Check out beesocial.dev/@adamghill. 🐝
Profile on beesocial.dev: https://beesocial.dev/@adamghill
100
adamghill @adamghill.com · 21/06/2025
@sjbitcode.bsky.social and I have been working on a fun side project and we are finally ready to launch a very early MVP. ✨ beesocial.dev ✨ Current features: - sign up - create a profile with a description, social media, and skills - add links or collections of links
Landing page for beesocial.dev. Highlight your projects, build your hive.Add skills to show off your expertise on beesocial.dev.
241
adamghill @adamghill.com · 26/05/2025
genius.com/Kimya-dawson...
News from the ministry of make-believe that reach a tarmac in Minneapolis
Middle seat, yesterday the cells inside his chest were growing baby teeth
Today a raven radiated vacancy
Wait-two years ago a friend of mine
Called me to redefine all enemy-kind
I'm at the hospital in twenty-four and no one knew the future
I'll take it everybody knows the future
Antibodies hatching in a hella back with no room to maneuver
Like disappearing pills into the masticated fuchsia
I asked you how you feeling, you told me like a robot
I gave you a Nintendo, you gave yourself a mohawk
You let us wheel you down beneath the leaning tower of flow charts
To be around your beats without a beeping sound of bogart
100
adamghill @adamghill.com · 18/05/2025
Just published 0.39.0 of Coltrane, my minimal app framework for content sites. 🎶 This release includes a fix for the `to_html` template filter which provides a way to convert markdown into HTML in the template. #Django #markdown #HTML #Python
<p class="text:sm sm:text-base text-gray-600">
  {{ profile.description|to_html }}
</p>
010
adamghill @adamghill.com · 15/05/2025
no I will not “see the research”, LinkedIn thank you very much
Unplugging may hurt your career - even if it makes you better at your job.
See the research.
110
adamghill @adamghill.com · 11/05/2025
Me: focus focus focus My brain: what’s that over there?! Me:
just another way to say “FOCUS ADAM JEEZ”
010
adamghill @adamghill.com · 11/05/2025
this is my kyponite maxrozen.com/on-four-year... @rozenmd.com
No other side projects.

>the person who chases two rabbits catches neither

Of course, there are exceptional folks out there chasing a dozen rabbits and managing to catch some of them - I know myself well enough to realize that I'm not that person.

Building out the marketing and sales processes to take a business from $0 to $500 MRR is challenging enough. I don't see a point in repeating the hardest part of starting a business over and over again, instead of doubling down on what's already working (this is also a lesson for picking a marketing approach, more on that later).
130
adamghill @adamghill.com · 30/04/2025
17 years ago: code.djangoproject.com/ticket/8652. 😩 I’m sure it’s more complicated than this, but I just tried adding the `re.DOTALL` flag to github.com/django/djang... on a whim and it seems to work with a simple test. 😇
`tag_re = re.compile(r"({%.*?%}|{{.*?}}|{#.*?#})", re.DOTALL)` allows this to work ```{%
block
content
%}```
000
adamghill @adamghill.com · 28/04/2025
You had me at high-concept comedy.
Tags for I’m a Virgo include high-concept comedy, quirky comedy, supernatural fantasy.
000
adamghill @adamghill.com · 19/04/2025
It’s impressive how fast the scammers start looking for WordPress or PHP files to exploit on a new domain. I’ve been incrementally adding to this CloudFlare WAF regex to block most of the dumbest requests.
CloudFlare WAF to block anything related to PHP.
261
adamghill @adamghill.com · 29/03/2025
I spent some time working on this idea at one point, but never got to anything release-able. There is github.com/nephila/djan... which seems like an approach, although I haven’t tried it.
I don’t hate using a DX like django install {package} to install a new package into my application. It would be really cool if we could even add the package into INSTALLED_APPS and make some other suggestion changes if the package could be installed in our urls.py or even explore optional settings that the package might support.
110
adamghill @adamghill.com · 23/03/2025
0.19.0 of `dj-angles` is released! 🎉 - inline templates: dj-angles.adamghill.com/en/latest/te... - fix delay attribute in ajax-form - output a stringified result from the `call` template tag 📖 dj-angles.adamghill.com 🛠️ codeberg.org/adamghill/dj... 📦 pypi.org/project/dj-a... #Django #HTML #Python
{% template field(name, value='') %}
<input name="{{ name }}" value="{{ value }}" />
{% endtemplate %}

{% call field('first-name') %}
<!-- 
<input name="first-name" value="" />
-->

{% call field('last-name', value='Smith') %}
<!-- 
<input name="last-name" value="Smith" />
-->
020
adamghill @adamghill.com · 22/03/2025
Playing around with a way to declare ad-hoc “templates” in a #Django template and then “call” them to render different values. Similar idea to mozilla.github.io/nunjucks/tem....
{% template field(name, value='', type='text') %}
<div class="field">
  <input type="{{ type }}" name="{{ name }}" value="{{ value }}" />
</div>
{% endtemplate %}

{% call field('cool-field', value=12345) %}
<!-- 
<div class="field">
  <input type="text" name="cool-field" value="12345" />
</div>
-->

{% call field('another-field', value='good value') %}
<!-- 
<div class="field">
  <input type="text" name="another-field" value="good value" />
</div>
-->
010
adamghill @adamghill.com · 21/03/2025
Example 47,829 of the frustratingly lazy HN comment: rename your project b/c the name conflicts with something else, b/c it's close to another word, b/c I don't like that word, b/c it's hard to Google, etc, etc. I got this comment for "django-unicorn" because it was too close to "gunicorn". Ok. 🙄
HN comment: "Nice, but your terminal app has a name collision with the long lived ''screen'' terminal multiplexer utility:

https://www.gnu.org/software/screen/manual/screen.html

Please kindly rename yours."
010
adamghill @adamghill.com · 21/03/2025
"Kind of a lot." Fair. 😂
Header: dj-angles

Use HTML-like elements in Django templates, e.g. <dj-partial /> instead of {% include 'partial.html' %}

An attempt to replace {% with <dj- in the whole DTL. Kind of a lot.
000
adamghill @adamghill.com · 19/03/2025
1. git clone codeberg.org/adamghill/dj... 2. Add a setting for “html.customData” in VS Code that points to the `html.html-data.json` file in the repo I’ll look into making an actual extension that can be downloaded in the VS Code marketplace later!
100
adamghill @adamghill.com · 18/03/2025
kupajo.com/stamina-is-a...
It’s the ability to chip away at goals despite a lack of visible progress. To hold focus and presence in a world incentivized to distract you. To stay patient. To be on time. To push through difficult material. To follow instructions or proceed without them. To keep an open mind and be willing to renew your perspective.
000
adamghill @adamghill.com · 17/03/2025
Published 0.18.0 of `dj-angles` to provide a way to add #AJAX forms to #Django. The form tag will submit to the endpoint specified in the action via fetch and swap in the resulting #HTML. Very similar to #HTMX. 📖 dj-angles.adamghill.com 📦 pypi.org/project/dj-a... 🛠️ codeberg.org/adamghill/dj...
140
adamghill @adamghill.com · 15/03/2025
Just released 0.15.0 of `dj-angles` with 2 new template tags. 🚀 - `call`: evaluate functions directly from a #Django template - `model`: make database model queries directly from a Django template 📖 dj-angles.adamghill.com 📦 pypi.org/project/dj-a... 🛠️ codeberg.org/adamghill/dj...
An example of how to use the call template tag.

```
{% call book.is_read(request.user) as current_user_read %}
```Example of using model template tag.

```
{% model Book.objects.filter(published__gte='2020-01-01') as books %}
```
130
adamghill @adamghill.com · 11/03/2025
After building this out, I ended up at a realization: I could query database models from the template. Not quite sure if this is genius or madness. 😇 Next step is to make a custom HTML tag in dj-angles so it doesn't look like DTL at all.
A Django template with the following:

{% load dj_angles %}

{% model Movie.objects.filter(id=1) as movie1 %}

{{ movie1 }}
```
130
adamghill @adamghill.com · 09/03/2025
I understand why #Django prevents calling arbitrary functions from the template, but that doesn’t stop me from wanting to do it. 🥹 With a normal simple_tag trying to pass the function, e.g. “movie.has_vote" will result in an empty string, so I had to make a custom node to parse it correctly. 😅
Two approaches to call arbitrary functions on an object. First is using a simple_tag so requires the function name as a string. The second takes in the object with a funciton name on it, e.g. “movie.has_vote”.
270