<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Johnny Metz</title>
    <link>https://johnnymetz.com/</link>
    <description>Recent content on Johnny Metz</description>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Sun, 22 Mar 2026 00:12:00 -0700</lastBuildDate>
    <atom:link href="https://johnnymetz.com/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Django Custom Managers Are Silently Leaking Data</title>
      <link>https://johnnymetz.com/posts/django-custom-managers-data-leak/</link>
      <pubDate>Sun, 22 Mar 2026 00:12:00 -0700</pubDate>
      <guid>https://johnnymetz.com/posts/django-custom-managers-data-leak/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://docs.djangoproject.com/en/6.0/topics/db/managers/#custom-managers&#34;&gt;Django custom managers&lt;/a&gt; are a common way to exclude rows by default, such as inactive or soft-deleted rows. However, they don&amp;rsquo;t run everywhere you&amp;rsquo;d expect, which leads to unintended data exposure. This post covers where that happens and how to fix it.&lt;/p&gt;
&lt;h2 id=&#34;the-setup&#34;&gt;The Setup&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s model stores and products with a soft-deletable relationship:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Store&lt;/span&gt;(models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Model):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;CharField(max_length&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;255&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Product&lt;/span&gt;(models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Model):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;CharField(max_length&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;255&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;StoreProductManager&lt;/span&gt;(models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Manager):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;get_queryset&lt;/span&gt;(self):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; super()&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;get_queryset()&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;filter(active&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;StoreProduct&lt;/span&gt;(models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Model):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    store &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;ForeignKey(Store, on_delete&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;CASCADE)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    product &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;ForeignKey(Product, on_delete&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;CASCADE)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    active &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;BooleanField(default&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    created_at &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;DateTimeField(auto_now_add&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    objects &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; StoreProductManager()  &lt;span style=&#34;color:#75715e&#34;&gt;# default: active only&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    all_objects &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Manager()   &lt;span style=&#34;color:#75715e&#34;&gt;# escape hatch: everything&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The custom manager is declared first, making it the &lt;a href=&#34;https://docs.djangoproject.com/en/6.0/topics/db/managers/#default-managers&#34;&gt;default manager&lt;/a&gt;. That feels like it should protect us everywhere, but it doesn&amp;rsquo;t.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Django Time-Based Lookups: A Performance Trap</title>
      <link>https://johnnymetz.com/posts/django-time-based-lookups-performance/</link>
      <pubDate>Mon, 19 Jan 2026 00:00:00 -0700</pubDate>
      <guid>https://johnnymetz.com/posts/django-time-based-lookups-performance/</guid>
      <description>&lt;p&gt;Django&amp;rsquo;s &lt;a href=&#34;https://docs.djangoproject.com/en/6.0/topics/db/queries/#field-lookups-intro&#34;&gt;&lt;code&gt;field lookups&lt;/code&gt;&lt;/a&gt; are one of the ORM&amp;rsquo;s best features, but time-based lookups can quietly bypass database indexes, turning fast queries into expensive full table scans.&lt;/p&gt;
&lt;h2 id=&#34;a-slow-production-query&#34;&gt;A Slow Production Query&lt;/h2&gt;
&lt;p&gt;I ran into this while debugging a 30 second query on a large table (~25 million rows):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Event&lt;/span&gt;(models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Model):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    timestamp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;DateTimeField(db_index&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Event&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;objects&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;filter(timestamp__date&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;datetime&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;date(&lt;span style=&#34;color:#ae81ff&#34;&gt;2026&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;))&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;count()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It generates SQL like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;SELECT&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;COUNT&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt; event
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;WHERE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;timestamp&lt;/span&gt;::date&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;2026-01-05&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;At first glance, it looked totally reasonable — a simple filter on an indexed field. But after checking the query plan, I discovered the issue: the query can&amp;rsquo;t use the index and falls back to a full table scan because it casts the field to a date.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Avoiding Duplicate Objects in Django Querysets</title>
      <link>https://johnnymetz.com/posts/avoiding-duplicate-objects-in-django-querysets/</link>
      <pubDate>Sat, 03 Jan 2026 00:00:00 -0700</pubDate>
      <guid>https://johnnymetz.com/posts/avoiding-duplicate-objects-in-django-querysets/</guid>
      <description>&lt;p&gt;When filtering Django querysets across relationships, you can easily end up with duplicate objects in your results. This is a common gotcha that happens with both one-to-many (1:N) and many-to-many (N:N) relationships. Let&amp;rsquo;s explore why this happens and the best way to avoid it.&lt;/p&gt;
&lt;h2 id=&#34;the-problem&#34;&gt;The Problem&lt;/h2&gt;
&lt;p&gt;When you filter a queryset by traversing a relationship, Django performs a SQL JOIN. If a parent object has multiple related objects that match your filter, the parent object appears multiple times in the result set.&lt;/p&gt;</description>
    </item>
    <item>
      <title>7 Heroku Features Every Developer Should Be Using</title>
      <link>https://johnnymetz.com/posts/heroku-features-you-should-be-using/</link>
      <pubDate>Sat, 13 Sep 2025 12:00:00 -0600</pubDate>
      <guid>https://johnnymetz.com/posts/heroku-features-you-should-be-using/</guid>
      <description>&lt;p&gt;Heroku makes hosting simple, but most developers overlook its advanced capabilities. After years of running apps on the platform, I&amp;rsquo;ve found several underrated features that speed up your workflow and make your apps more reliable. Here are seven you shouldn&amp;rsquo;t miss.&lt;/p&gt;
&lt;h2 id=&#34;1-preboot&#34;&gt;1. Preboot&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://devcenter.heroku.com/articles/preboot&#34;&gt;Preboot&lt;/a&gt; spins up new dynos and starts routing traffic to them before the old ones are terminated. The result is seamless, zero-downtime deployments.&lt;/p&gt;
&lt;p&gt;The tricky part is knowing when the cutover is complete, since the Heroku dashboard doesn&amp;rsquo;t show it. Use this command to confirm when the new dynos are live:&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Django db_default Gotcha That Breaks Your Code</title>
      <link>https://johnnymetz.com/posts/django-db-default-gotcha/</link>
      <pubDate>Sun, 03 Aug 2025 13:46:58 -0700</pubDate>
      <guid>https://johnnymetz.com/posts/django-db-default-gotcha/</guid>
      <description>&lt;p&gt;Starting in Django 5.0, you can use &lt;a href=&#34;https://docs.djangoproject.com/en/5.2/ref/models/fields/#db-default&#34;&gt;&lt;code&gt;db_default&lt;/code&gt;&lt;/a&gt; to define database-level default values for model fields. It&amp;rsquo;s a great feature but comes with a subtle and dangerous gotcha that can silently break your code before the object is ever saved.&lt;/p&gt;
&lt;h2 id=&#34;the-gotcha-in-action&#34;&gt;The Gotcha in Action&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s say you&amp;rsquo;re building a simple task manager, and you want to track whether a task is completed:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; django.db &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; models
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Task&lt;/span&gt;(models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Model):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    is_completed &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;BooleanField(db_default&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;False&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;db_default&lt;/code&gt; option ensures the database applies the default in raw &lt;code&gt;INSERT&lt;/code&gt; queries and &lt;a href=&#34;https://johnnymetz.com/posts/multistep-database-changes/#backward-compatible&#34;&gt;prevents errors during a rolling deployment&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Stop Using Django&#39;s squashmigrations: There&#39;s a Better Way</title>
      <link>https://johnnymetz.com/posts/squash-django-migrations/</link>
      <pubDate>Sat, 26 Jul 2025 17:00:00 -0700</pubDate>
      <guid>https://johnnymetz.com/posts/squash-django-migrations/</guid>
      <description>&lt;p&gt;Squashing merges multiple database migrations into a single consolidated file to speed up database setup and tidy up history. Django&amp;rsquo;s &lt;a href=&#34;https://docs.djangoproject.com/en/stable/topics/migrations/#squashing-migrations&#34;&gt;&lt;code&gt;squashmigrations&lt;/code&gt;&lt;/a&gt; command promises to handle this, but it&amp;rsquo;s error-prone and unnecessarily complex. A clean reset is faster and simpler.&lt;/p&gt;
&lt;h2 id=&#34;-why-squashmigrations-falls-short&#34;&gt;⚠️ Why &lt;code&gt;squashmigrations&lt;/code&gt; Falls Short&lt;/h2&gt;
&lt;h3 id=&#34;broken-in-practice&#34;&gt;Broken in Practice&lt;/h3&gt;
&lt;p&gt;In medium-to-large projects, I&amp;rsquo;ve consistently seen &lt;code&gt;squashmigrations&lt;/code&gt; generate poor results, such as failing to optimize basic no-ops (like adding and deleting the same field) and even breaking migrations. The &lt;a href=&#34;https://docs.djangoproject.com/en/stable/topics/migrations/#squashing-migrations&#34;&gt;official docs&lt;/a&gt; acknowledge this:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Speed Up Django Queries with values() over only()</title>
      <link>https://johnnymetz.com/posts/django-values-over-only/</link>
      <pubDate>Sun, 29 Jun 2025 13:11:26 -0700</pubDate>
      <guid>https://johnnymetz.com/posts/django-values-over-only/</guid>
      <description>&lt;p&gt;If your Django queries feel slow, the problem might not be your database — it might be your ORM. Recently, I was working with a query that took 25 seconds to run through the Django ORM, but the underlying SQL completed in just 2 seconds. With a single change, I got the ORM query down to 2 seconds as well — and reduced the memory footprint by 70%.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s walk through what happened, and why using &lt;code&gt;.values()&lt;/code&gt; instead of &lt;code&gt;.only()&lt;/code&gt; can dramatically improve performance.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Avoiding PostgreSQL Pitfalls: The Hidden Cost of Failing Inserts</title>
      <link>https://johnnymetz.com/posts/postgresql-failing-insert/</link>
      <pubDate>Sun, 15 Jun 2025 18:00:00 -0700</pubDate>
      <guid>https://johnnymetz.com/posts/postgresql-failing-insert/</guid>
      <description>&lt;p&gt;A simple insert query turned into a silent performance killer.&lt;/p&gt;
&lt;p&gt;Our frontend pings our server every few minutes to track device activity. Each ping attempts to insert a row into a &lt;code&gt;DevicePingDaily&lt;/code&gt; table, which has a unique constraint on &lt;code&gt;(device_id, date)&lt;/code&gt; to ensure only one record per device per day.&lt;/p&gt;
&lt;p&gt;In Django, the logic looked like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;try&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    DevicePingDaily&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;objects&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;create(device&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;device, date&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;today)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;except&lt;/span&gt; IntegrityError:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;pass&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It seemed harmless. But as traffic grew, latency spiked and API timeouts increased. Observability tools quickly pointed to the culprit:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Disable Redundant Gunicorn Access Logs on Heroku</title>
      <link>https://johnnymetz.com/posts/disable-gunicorn-access-logs/</link>
      <pubDate>Mon, 25 Nov 2024 12:00:00 -0800</pubDate>
      <guid>https://johnnymetz.com/posts/disable-gunicorn-access-logs/</guid>
      <description>&lt;p&gt;When hosting an application on &lt;a href=&#34;https://www.heroku.com/&#34;&gt;Heroku&lt;/a&gt;, managing logs efficiently is crucial for maintaining system health and keeping costs down. Heroku provides built-in logging for all incoming requests, but by default, &lt;a href=&#34;https://gunicorn.org/&#34;&gt;Gunicorn&lt;/a&gt;, the Python HTTP server often used in Heroku deployments, also logs incoming requests. This duplication can clutter your logs, making them harder to parse and more expensive to store. Let&amp;rsquo;s explore why this redundancy exists and how to fix it.&lt;/p&gt;
&lt;h2 id=&#34;heroku-router-logs&#34;&gt;Heroku Router Logs&lt;/h2&gt;
&lt;p&gt;Heroku&amp;rsquo;s Router automatically logs all incoming HTTP requests, providing a wealth of data for monitoring and debugging your application. These logs are always enabled and include detailed information, such as the HTTP method and URL path of the request, the response status code, the client&amp;rsquo;s IP address, and the request processing time (see &lt;a href=&#34;https://devcenter.heroku.com/articles/http-routing#heroku-router-log-format&#34;&gt;Heroku Router Log Format&lt;/a&gt;).&lt;/p&gt;</description>
    </item>
    <item>
      <title>5 Ways to Get the Latest Book Per Author in Django</title>
      <link>https://johnnymetz.com/posts/latest-book-per-author/</link>
      <pubDate>Thu, 14 Nov 2024 12:00:00 -0700</pubDate>
      <guid>https://johnnymetz.com/posts/latest-book-per-author/</guid>
      <description>&lt;p&gt;In a Django application, fetching the latest record for each group is a common yet challenging task, especially when working with large datasets. Whether you&amp;rsquo;re building an analytics dashboard or managing grouped data, finding an efficient solution is key. In this blog post, we&amp;rsquo;ll explore five different approaches to tackle this problem, ranked from least to most effective based on performance and readability, using the following &lt;code&gt;Book&lt;/code&gt; model:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Book&lt;/span&gt;(models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Model):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    title &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;CharField(max_length&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;255&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    author &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;ForeignKey(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        Author, on_delete&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;CASCADE, related_name&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;books&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    genre &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;CharField(max_length&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;255&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    published_at &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;DateTimeField()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    is_featured &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;BooleanField(default&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;False&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;solution-1-python-max-with-prefetch&#34;&gt;Solution 1: Python Max with Prefetch&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;latest_books &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    max(author&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;books&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;all(), key&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;lambda&lt;/span&gt; x: x&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;published_at, default&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; author &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; Author&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;objects&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;prefetch_related(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;books&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Performs heavy computation in Python rather than leveraging the database, which is &lt;a href=&#34;https://docs.djangoproject.com/en/5.1/topics/db/optimization/#do-database-work-in-the-database-rather-than-in-python&#34;&gt;bad for performance&lt;/a&gt;. Also makes two database queries (better solutions do it in one).&lt;/p&gt;</description>
    </item>
    <item>
      <title>Zero Downtime Django Deployments with Multistep Database Changes</title>
      <link>https://johnnymetz.com/posts/multistep-database-changes/</link>
      <pubDate>Sun, 27 Oct 2024 12:00:00 -0700</pubDate>
      <guid>https://johnnymetz.com/posts/multistep-database-changes/</guid>
      <description>&lt;p&gt;Preventing downtime during deployments is crucial for maintaining service availability and ensuring a positive user experience. Blue-green deployments have emerged as a popular strategy to achieve this goal. However, they introduce challenges, especially when dealing with database changes. This article delves into what blue-green deployments are, why database changes can be tricky in this context, and how to navigate common change scenarios effectively in Django.&lt;/p&gt;
&lt;h2 id=&#34;blue-green-deployments&#34;&gt;Blue-Green Deployments&lt;/h2&gt;
&lt;p&gt;A blue-green deployment is a release management strategy that utilizes two separate production environments called &amp;ldquo;blue&amp;rdquo; and &amp;ldquo;green&amp;rdquo;. At any given time, only one environment is live, serving all production traffic. Changes are deployed to green, and after thorough testing, traffic is switched over from the blue to green. This approach minimizes downtime and provides a quick rollback option by reverting traffic to blue if issues occur.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Mastering Code Search with JetBrains Scope</title>
      <link>https://johnnymetz.com/posts/jetbrains-scope/</link>
      <pubDate>Sat, 30 Sep 2023 10:55:29 -0400</pubDate>
      <guid>https://johnnymetz.com/posts/jetbrains-scope/</guid>
      <description>&lt;h2 id=&#34;background&#34;&gt;Background&lt;/h2&gt;
&lt;p&gt;As software engineers, one of the most crucial skills we develop is the ability to search through code efficiently. Whether it&amp;rsquo;s finding a specific function, understanding how a certain feature is implemented, or tracing a bug, being able to quickly navigate a codebase is essential for productivity. However, many codebases can be complex and sprawling, leading to noisy search results that hinder rather than aid our progress. JetBrains provides a few tools to help you refine your code search and focus on what&amp;rsquo;s important.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Supercharge Your Django App: 7 Sneaky Tricks to Crush Slow Database Queries</title>
      <link>https://johnnymetz.com/posts/slow-django-database-queries/</link>
      <pubDate>Sun, 13 Aug 2023 12:15:13 -0400</pubDate>
      <guid>https://johnnymetz.com/posts/slow-django-database-queries/</guid>
      <description>&lt;p&gt;Optimizing Django query performance is critical for building performant web applications. Django provides many tools and methods for optimizing database queries in its &lt;a href=&#34;https://docs.djangoproject.com/en/4.2/topics/db/optimization/&#34;&gt;Database access optimization documentation&lt;/a&gt;. In this blog post, we will explore a collection of additional and essential tips I&amp;rsquo;ve compiled over the years to help you pinpoint and resolve your inefficient Django queries.&lt;/p&gt;
&lt;h2 id=&#34;kill-long-running-queries-with-a-statement-timeout&#34;&gt;Kill Long-Running Queries with a Statement Timeout&lt;/h2&gt;
&lt;p&gt;PostgreSQL supports a &lt;a href=&#34;https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-STATEMENT-TIMEOUT&#34;&gt;&lt;code&gt;statement_timeout&lt;/code&gt;&lt;/a&gt; parameter that allows you to set a maximum time limit per query. This is useful for preventing long-running queries from tying up precious resources and slowing down your application. My team at &lt;a href=&#34;https://www.pixiebrix.com/&#34;&gt;PixieBrix&lt;/a&gt; experienced an incident where a few long-running queries resulted in a full database outage. Setting a statement timeout in your Django settings can help prevent this from happening.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Optimize Django Query Performance by combining Select Related and Prefetch Related</title>
      <link>https://johnnymetz.com/posts/combine-select-related-prefetch-related/</link>
      <pubDate>Sat, 13 May 2023 15:48:39 -0400</pubDate>
      <guid>https://johnnymetz.com/posts/combine-select-related-prefetch-related/</guid>
      <description>&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;When building a Django application, one of the key challenges developers face is optimizing database query performance. Django provides two tools,&lt;code&gt;select_related&lt;/code&gt; and &lt;code&gt;prefetch_related&lt;/code&gt;, that reduce the number of database queries, and increase the performance of your application.&lt;/p&gt;
&lt;p&gt;This blog post explores the power of these two methods and how to combine them to maximize your application&amp;rsquo;s query performance.&lt;/p&gt;
&lt;p&gt;My team at &lt;a href=&#34;https://www.pixiebrix.com/&#34;&gt;PixieBrix&lt;/a&gt; implemented these techniques and have seen a significant improvement in query performance and customer satisfaction.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Free up disk space with Docker prune</title>
      <link>https://johnnymetz.com/posts/docker-prune/</link>
      <pubDate>Sat, 21 Jan 2023 14:11:25 -0500</pubDate>
      <guid>https://johnnymetz.com/posts/docker-prune/</guid>
      <description>&lt;p&gt;Docker is a platform for developing, shipping and running applications in isolated, lightweight and portable containers. It is a critical part of a developer&amp;rsquo;s toolbelt and one I use just about everyday.&lt;/p&gt;
&lt;p&gt;Docker can consume a large amount of disk space. Per the &lt;a href=&#34;https://docs.docker.com/config/pruning/&#34;&gt;Docker documentation&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Docker takes a conservative approach to cleaning up unused objects (often referred to as &amp;ldquo;garbage collection&amp;rdquo;), such as images, containers, volumes, and networks: these objects are generally not removed unless you explicitly ask Docker to do so. This can cause Docker to use extra disk space.&lt;/p&gt;</description>
    </item>
    <item>
      <title>[Cross-Post] Django performance: Sort by a Custom Order</title>
      <link>https://johnnymetz.com/posts/sort-django-queryset-by-custom-order/</link>
      <pubDate>Mon, 02 Jan 2023 17:00:00 -0800</pubDate>
      <guid>https://johnnymetz.com/posts/sort-django-queryset-by-custom-order/</guid>
      <description>&lt;p&gt;See the post here: &lt;a href=&#34;https://www.pixiebrix.com/blog/sort-django-queryset-by-custom-order&#34;&gt;Sort a Django Queryset by a Custom Order&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Disable a direct push to GitHub main branch</title>
      <link>https://johnnymetz.com/posts/disable-direct-push-to-main-branch/</link>
      <pubDate>Thu, 29 Dec 2022 10:36:08 -0800</pubDate>
      <guid>https://johnnymetz.com/posts/disable-direct-push-to-main-branch/</guid>
      <description>&lt;p&gt;On a development team, you never want to push directly to the &lt;code&gt;main&lt;/code&gt; branch. Instead, you want to require changes to be made through pull requests so they can be properly reviewed by other developers.&lt;/p&gt;
&lt;p&gt;Some developers, including myself, occasionally forget to push to a new branch so I like to have an automated check to prevent this mistake. Here are two methods to block direct pushes to the GitHub &lt;code&gt;main&lt;/code&gt; branch.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Using Hadolint, a Dockerfile linter, To Enforce Best Practices</title>
      <link>https://johnnymetz.com/posts/hadolint/</link>
      <pubDate>Thu, 17 Mar 2022 19:32:01 -0700</pubDate>
      <guid>https://johnnymetz.com/posts/hadolint/</guid>
      <description>&lt;p&gt;Misconfigured Docker containers can be slow, heavy and difficult to maintain. This leads to sluggish releases, high storage costs and frustrated developers. Moreover, inadequate Docker containers can be a major security liability. A recent report by Aqua Security found that &lt;a href=&#34;https://www.aquasec.com/news/2021-cloud-native-threat-report-reveals-new-threats/&#34;&gt;50% of new Docker instances are attacked within 56 minutes&lt;/a&gt; of being deployed. Docker problems can be devastating for any business and software teams need to put in the time and energy to alleviate these risks.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Dockerize a Next.js app using multi-stage builds</title>
      <link>https://johnnymetz.com/posts/dockerize-nextjs-app/</link>
      <pubDate>Sat, 26 Feb 2022 01:14:31 -0800</pubDate>
      <guid>https://johnnymetz.com/posts/dockerize-nextjs-app/</guid>
      <description>&lt;div
  class=&#39;alert alert-info&#39;
  role=&#34;alert&#34;
&gt;See the &lt;a href=&#34;https://github.com/johnnymetz/docker-nextjs&#34;&gt;&lt;strong&gt;source code&lt;/strong&gt;&lt;/a&gt; for a working example.&lt;/div&gt;

&lt;p&gt;&lt;a href=&#34;https://nextjs.org/&#34;&gt;Next.js&lt;/a&gt; is a popular React Framework that comes with a lot of great features such as hybrid static &amp;amp; server rendering, smart bundling, file system routing, and much more. I prefer it over vanilla React.&lt;/p&gt;
&lt;p&gt;When we dockerize a Next.js application, we want the final production and development images to be small, fast to build and easy to maintain. Let&amp;rsquo;s see how we can use &lt;a href=&#34;https://docs.docker.com/develop/develop-images/multistage-build/&#34;&gt;multi-stage builds&lt;/a&gt; and other image optimization techniques to create the ideal images.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Dockerize your Cypress tests</title>
      <link>https://johnnymetz.com/posts/dockerize-your-cypress-tests/</link>
      <pubDate>Mon, 31 Jan 2022 21:08:44 -0800</pubDate>
      <guid>https://johnnymetz.com/posts/dockerize-your-cypress-tests/</guid>
      <description>&lt;div
  class=&#39;alert alert-info&#39;
  role=&#34;alert&#34;
&gt;See the &lt;a href=&#34;https://github.com/johnnymetz/cypress-docker-django-nextjs&#34;&gt;&lt;strong&gt;source code&lt;/strong&gt;&lt;/a&gt; for a working example.&lt;/div&gt;

&lt;p&gt;UI testing is a critical part of any modern web application. My favorite testing framework is &lt;a href=&#34;https://docs.cypress.io&#34;&gt;&lt;strong&gt;Cypress&lt;/strong&gt;&lt;/a&gt; which enables you to write clean, fast and reliable tests. It consists of two main commands:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cypress run&lt;/code&gt;: Runs Cypress tests from the CLI without a GUI. Used mostly in CI/CD.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cypress open&lt;/code&gt;: Opens Cypress in an interactive GUI. Used for local development.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I like to dockerize my entire application so it can be run anywhere (my machine, coworker&amp;rsquo;s machine, CI/CD, etc.) and Cypress is no exception. We&amp;rsquo;re going to dockerize the &lt;code&gt;cypress run&lt;/code&gt; and &lt;code&gt;cypress open&lt;/code&gt; commands for a simple Todo application written in Django and Next.js (check out the &lt;a href=&#34;https://github.com/johnnymetz/cypress-docker-django-nextjs&#34;&gt;source code&lt;/a&gt;).&lt;/p&gt;</description>
    </item>
    <item>
      <title>Free up Django CPU usage in Docker with Watchman</title>
      <link>https://johnnymetz.com/posts/free-up-django-cpu-usage-in-docker-with-watchman/</link>
      <pubDate>Tue, 04 Jan 2022 23:27:56 -0800</pubDate>
      <guid>https://johnnymetz.com/posts/free-up-django-cpu-usage-in-docker-with-watchman/</guid>
      <description>&lt;p&gt;You can use &lt;a href=&#34;https://github.com/facebook/watchman&#34;&gt;watchman&lt;/a&gt; in your Django project to make auto-reloads more CPU efficient. Adam Johnson&amp;rsquo;s &lt;a href=&#34;https://adamj.eu/tech/2021/01/20/efficient-reloading-in-djangos-runserver-with-watchman/&#34;&gt;Efficient Reloading in Django&amp;rsquo;s Runserver With Watchman&lt;/a&gt; blog post does an excellent job describing how to set this up. I highly recommend giving it a read. The tutorial explains how to install watchman on macOS with &lt;code&gt;brew install watchman&lt;/code&gt; but does not explain how to install it in a Python docker container. Considering all of my Django projects are dockerized, I decided to figure it out.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Set Django Model Field Choices in your Frontend the Right Way</title>
      <link>https://johnnymetz.com/posts/set-django-model-field-choices-in-frontend/</link>
      <pubDate>Wed, 01 Dec 2021 10:31:13 -0800</pubDate>
      <guid>https://johnnymetz.com/posts/set-django-model-field-choices-in-frontend/</guid>
      <description>&lt;p&gt;In Django, you can define a set of &lt;a href=&#34;https://docs.djangoproject.com/en/3.2/ref/models/fields/#choices&#34;&gt;choices&lt;/a&gt; for any field.
If you&amp;rsquo;re using a SPA frontend, such as React or Vue, then you&amp;rsquo;ll need to access these choices in a form. Let&amp;rsquo;s look at two ways to do this.&lt;/p&gt;
&lt;p&gt;As an example, we&amp;rsquo;ll use the following &lt;code&gt;Device&lt;/code&gt; model:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Device&lt;/span&gt;(models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Model):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Size&lt;/span&gt;(models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;TextChoices):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        SMALL &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;S&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        MEDIUM &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;M&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        LARGE &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;L&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;CharField(max_length&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;255&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    size &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;CharField(max_length&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;255&lt;/span&gt;, choices&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;Size&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;choices)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;hardcode-choices-in-frontend&#34;&gt;Hardcode choices in frontend&lt;/h2&gt;
&lt;p&gt;The fastest approach is to harcode these choices in the frontend.&lt;/p&gt;</description>
    </item>
    <item>
      <title>5 ways to get all Django objects with a related object</title>
      <link>https://johnnymetz.com/posts/five-ways-to-get-django-objects-with-a-related-object/</link>
      <pubDate>Fri, 01 Oct 2021 13:08:48 -0700</pubDate>
      <guid>https://johnnymetz.com/posts/five-ways-to-get-django-objects-with-a-related-object/</guid>
      <description>&lt;p&gt;In Django, a &lt;a href=&#34;https://docs.djangoproject.com/en/3.2/ref/models/relations/&#34;&gt;related object&lt;/a&gt; is a model instance used in the one-to-many or many-to-many context.&lt;/p&gt;
&lt;p&gt;For example, let&amp;rsquo;s look at the built-in &lt;code&gt;User&lt;/code&gt; model, which has a many-to-many relationship with the &lt;code&gt;Group&lt;/code&gt; model.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;User&lt;/span&gt;(models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Model):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    groups &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;ManyToManyField(Group, related_name&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;groups&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For any given &lt;code&gt;User&lt;/code&gt; object, all linked &lt;code&gt;Group&lt;/code&gt; objects are called &amp;ldquo;related objects&amp;rdquo;. Here are 5 ways to fetch all &lt;code&gt;User&lt;/code&gt; objects with at least one related &lt;code&gt;Group&lt;/code&gt; object.&lt;/p&gt;
&lt;h2 id=&#34;iterate-over-each-object-in-python&#34;&gt;Iterate over each object in Python&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;users &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; user &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; User&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;objects&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;prefetch_related(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;groups&amp;#34;&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; user&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;groups&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;exists():
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        users&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append(user)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Probably the most popular approach but there are two problems:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Why you need to use Subqueries in Django</title>
      <link>https://johnnymetz.com/posts/why-you-need-to-use-django-subqueries/</link>
      <pubDate>Wed, 21 Jul 2021 11:56:09 -0700</pubDate>
      <guid>https://johnnymetz.com/posts/why-you-need-to-use-django-subqueries/</guid>
      <description>&lt;p&gt;The Django ORM is a powerful tool but certain aspects of it are counterintuitive, such as the SQL order of execution.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s look at an example of this trap and how we can fix it using subqueries:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Book&lt;/span&gt;(models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Model):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Meta&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        constraints &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;UniqueConstraint(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                fields&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;edition&amp;#34;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                name&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%(app_label)s&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;_&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%(class)s&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;_unique_name_edition&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;CharField(max_length&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;255&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    edition &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;CharField(max_length&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;255&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    release_year &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;PositiveIntegerField(null&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I want to write a query that reads:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Check your Django Migrations on every commit</title>
      <link>https://johnnymetz.com/posts/check-django-migrations/</link>
      <pubDate>Sat, 08 May 2021 12:10:47 -0700</pubDate>
      <guid>https://johnnymetz.com/posts/check-django-migrations/</guid>
      <description>&lt;p&gt;Keeping your models in sync with your migrations is an important part of any Django app. My team and I frequently make changes to our models and we occassionally forget to create new migrations for those changes. This results in errors and data loss. Let&amp;rsquo;s look at an easy way to ensure your models and migrations are &lt;strong&gt;always&lt;/strong&gt; in sync:&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll use a simple &lt;code&gt;Product&lt;/code&gt; model.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Product&lt;/span&gt;(models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Model):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;CharField(max_length&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;255&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Let&amp;rsquo;s say we want to add a &lt;code&gt;quantity&lt;/code&gt; field.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Find all N&#43;1 violations in your Django app</title>
      <link>https://johnnymetz.com/posts/find-nplusone-violations/</link>
      <pubDate>Tue, 13 Apr 2021 23:10:50 -0800</pubDate>
      <guid>https://johnnymetz.com/posts/find-nplusone-violations/</guid>
      <description>&lt;p&gt;The N+1 problem is a common database performance issue. It plagues ORM&amp;rsquo;s, such as Django and SQLAlchemy, because it leads to your application making more database queries than necessary.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s look at a basic example in Django.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Artist&lt;/span&gt;(models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Model):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;CharField(max_length&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;255&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Song&lt;/span&gt;(models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Model):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    artist &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;ForeignKey(Artist, on_delete&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;CASCADE)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;CharField(max_length&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;255&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;print_songs&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; song &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; Song&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;objects&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;all():
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        print(&lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;song&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;artist&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;name&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; - &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;song&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;name&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now let&amp;rsquo;s create a unit test to ensure &lt;code&gt;print_songs&lt;/code&gt; runs successfully. We&amp;rsquo;re using &lt;code&gt;pytest&lt;/code&gt; and &lt;code&gt;pytest-django&lt;/code&gt; so we can create the test data using a &lt;a href=&#34;https://docs.pytest.org/en/stable/fixture.html&#34;&gt;pytest fixture&lt;/a&gt;. When we run the unit test, you&amp;rsquo;ll notice it passes and our songs are printed to the terminal. Everything seems fine on the surface.&lt;/p&gt;</description>
    </item>
    <item>
      <title></title>
      <link>https://johnnymetz.com/about/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://johnnymetz.com/about/</guid>
      <description>&lt;h1 id=&#34;about-me&#34;&gt;About Me&lt;/h1&gt;
&lt;p&gt;Full Stack Software Engineer located in San Francisco, CA. I specialize in web development with Python, Django, React, Docker, Kubernetes and AWS.&lt;/p&gt;
&lt;h2 id=&#34;popular-youtube-videos&#34;&gt;Popular YouTube Videos&lt;/h2&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/cdblJqEUDNo?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;hr&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/yGTGU3IPoWE?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;hr&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/A20PY5RxdI8?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;h2 id=&#34;side-projects&#34;&gt;Side Projects&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://notifire-app.netlify.app/&#34;&gt;Notifire&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Subscribe</title>
      <link>https://johnnymetz.com/subscribe/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://johnnymetz.com/subscribe/</guid>
      <description>Subscribe to my blog</description>
    </item>
  </channel>
</rss>
