{
  "@context": "https://schema.org",
  "@id": "https://aggr.aymericbeaumet.com/items/jvns-ca/2026-01-27-some-notes-on-starting-to-use-django/#webpage",
  "@type": [
    "WebPage",
    "ArchiveComponent"
  ],
  "articleBody": "Hello! One of my favourite things is starting to learn an Old Boring Technology that I’ve never tried before but that has been around for 20+ years. It feels really good when every problem I’m ever going to have has been solved already 1000 times and I can just get stuff done easily.\n\nI’ve thought it would be cool to learn a popular web framework like Rails or Django or Laravel for a long time, but I’d never really managed to make it happen. But I started learning Django to make a website a few months back, I’ve been liking it so far, and here are a few quick notes!\n\n### [less magic than Rails](https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#less-magic-than-rails)\n\nI spent some time [trying to learn Rails](https://jvns.ca/blog/2020/11/09/day-1--a-little-rails-/) in 2020, and while it was cool and I really wanted to like Rails (the Ruby community is great!), I found that if I left my Rails project alone for months, when I came back to it it was hard for me to remember how to get anything done because (for example) if it says `resources :topics` in your `routes.rb`, on its own that doesn’t tell you where the `topics` routes are configured, you need to remember or look up the convention.\n\nBeing able to abandon a project for months or years and then come back to it is really important to me (that’s how all my projects work!), and Django feels easier to me because things are more explicit.\n\nIn my small Django project it feels like I just have 5 main files (other than the settings files): `urls.py`, `models.py`, `views.py`, `admin.py`, and `tests.py`, and if I want to know where something else is (like an HTML template) is then it’s usually explicitly referenced from one of those files.\n\n### [a built-in admin](https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#a-built-in-admin)\n\nFor this project I wanted to have an admin interface to manually edit or view some of the data in the database. Django has a really nice built-in admin interface, and I can customize it with just a little bit of code.\n\nFor example, here’s part of one of my admin classes, which sets up which fields to display in the “list” view, which field to search on, and how to order them by default.\n\n```\n@admin.register(Zine)\nclass ZineAdmin(admin.ModelAdmin):\n    list_display = [\"name\", \"publication_date\", \"free\", \"slug\", \"image_preview\"]\n    search_fields = [\"name\", \"slug\"]\n    readonly_fields = [\"image_preview\"]\n    ordering = [\"-publication_date\"]\n```\n\n### [it’s fun to have an ORM](https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#it-s-fun-to-have-an-orm)\n\nIn the past my attitude has been “ORMs? Who needs them? I can just write my own SQL queries!”. I’ve been enjoying Django’s ORM so far though, and I think it’s cool how Django uses `__` to represent a `JOIN`, like this:\n\n```\nZine.objects\n    .exclude(product__order__email_hash=email_hash)\n```\n\nThis query involves 5 tables: `zines`, `zine_products`, `products`, `order_products`, and `orders`. To make this work I just had to tell Django that there’s a `ManyToManyField` relating “orders” and “products”, and another `ManyToManyField` relating “zines”, and “products”, so that it knows how to connect `zines`, `orders`, `products`.\n\nI definitely *could* write that query, but writing `product__order__email_hash` is a lot less typing, it feels a lot easier to read, and honestly I think it would take me a little while to figure out how to construct the query (which needs to do a few other things than just those joins).\n\nI have zero concern about the performance of my ORM-generated queries so I’m pretty excited about ORMs for now, though I’m sure I’ll find things to be frustrated with eventually.\n\n### [automatic migrations!](https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#automatic-migrations)\n\nThe other great thing about the ORM is migrations!\n\nIf I add, delete, or change a field in `models.py`, Django will automatically generate a migration script like `migrations/0006_delete_imageblob.py`.\n\nI assume that I could edit those scripts if I wanted, but so far I’ve just been running the generated scripts with no change and it’s been going great. It really feels like magic.\n\nI’m realizing that being able to do migrations easily is important for me right now because I’m changing my data model fairly often as I figure out how I want it to work.\n\n### [I like the docs](https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#i-like-the-docs)\n\nI had a bad habit of [never reading the documentation](https://www.youtube.com/watch?v=krMw1QTP2no) but I’ve been really enjoying the parts of Django’s docs that I’ve read so far. This isn’t by accident: Jacob Kaplan-Moss has a [talk from PyCon 2011](https://pyvideo.org/pycon-us-2011/pycon-2011--writing-great-documentation.html) on Django’s documentation culture.\n\nFor example the [intro to models](https://docs.djangoproject.com/en/6.0/topics/db/models/) lists the most important common fields you might want to set when using the ORM.\n\n### [using sqlite](https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#using-sqlite)\n\nAfter having a bad experience trying to operate Postgres and not being able to understand what was going on, I decided to run all of my small websites with SQLite instead. It’s been going way better, and I love being able to backup by just doing a `VACUUM INTO` and then copying the resulting single file.\n\nI’ve been following [these instructions](https://alldjango.com/articles/definitive-guide-to-using-django-sqlite-in-production) for using SQLite with Django in production.\n\nI think it should be fine because I’m expecting the site to have a few hundred writes per day at most, much less than [Mess with DNS](https://messwithdns.net/) which has a lot more of writes and has been working well (though the writes are split across 3 different SQLite databases).\n\n### [built in email (and more)](https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#built-in-email-and-more)\n\nDjango seems to be very “batteries-included”, which I love – if I want CSRF protection, or a `Content-Security-Policy`, or I want to send email, it’s all in there!\n\nFor example, I wanted to save the emails Django sends to a file in dev mode (so that it didn’t send real email to real people), which was just a little bit of configuration.\n\nI just put this `settings/dev.py`:\n\n```\nEMAIL_BACKEND = \"django.core.mail.backends.filebased.EmailBackend\"\nEMAIL_FILE_PATH = BASE_DIR / \"emails\"\n```\n\nand then set up the production email like this in `settings/production.py`\n\n```\nEMAIL_BACKEND = \"django.core.mail.backends.smtp.EmailBackend\"\nEMAIL_HOST = \"smtp.whatever.com\"\nEMAIL_PORT = 587\nEMAIL_USE_TLS = True\nEMAIL_HOST_USER = \"xxxx\"\nEMAIL_HOST_PASSWORD = os.getenv('EMAIL_API_KEY')\n```\n\nThat made me feel like if I want some other basic website feature, there’s likely to be an easy way to do it built into Django already.\n\n### [the settings file still feels like a lot](https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#the-settings-file-still-feels-like-a-lot)\n\nI’m still a bit intimidated by the `settings.py` file: Django’s settings system works by setting a bunch of global variables in a file, and I feel a bit stressed about… what if I make a typo in the name of one of those variables? How will I know? What if I type `WSGI_APPLICATOIN = \"config.wsgi.application\"` instead of `WSGI_APPLICATION`?\n\nI guess I’ve gotten used to having a Python language server tell me when I’ve made a typo and so now it feels a bit disorienting when I can’t rely on the language server support.\n\n### [that’s all for now!](https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#that-s-all-for-now)\n\nI haven’t really successfully used an actual web framework for a project before (right now almost all of my websites are either a single Go binary or static sites), so I’m interested in seeing how it goes!\n\nThere’s still lots for me to learn about, I still haven’t really gotten into Django’s form validation tooling or authentication systems.\n\nThanks to Marco Rogers for convincing me to give ORMs a chance.\n\n(we’re still experimenting with the comments-on-Mastodon system! [Here are the comments on Mastodon](https://comments.jvns.ca/post/115969229107460589)! tell me your favourite Django feature!)\n",
  "authors": [],
  "captured_at": "2026-09-19T21:30:23.395188495+00:00",
  "category": "programming",
  "content_html": "<p>Hello! One of my favourite things is starting to learn an Old Boring Technology that I’ve never tried before but that has been around for 20+ years. It feels really good when every problem I’m ever going to have has been solved already 1000 times and I can just get stuff done easily.</p>\n<p>I’ve thought it would be cool to learn a popular web framework like Rails or Django or Laravel for a long time, but I’d never really managed to make it happen. But I started learning Django to make a website a few months back, I’ve been liking it so far, and here are a few quick notes!</p>\n<h3><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#less-magic-than-rails\">less magic than Rails</a></h3>\n<p>I spent some time <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://jvns.ca/blog/2020/11/09/day-1--a-little-rails-/\">trying to learn Rails</a> in 2020, and while it was cool and I really wanted to like Rails (the Ruby community is great!), I found that if I left my Rails project alone for months, when I came back to it it was hard for me to remember how to get anything done because (for example) if it says <code>resources :topics</code> in your <code>routes.rb</code>, on its own that doesn’t tell you where the <code>topics</code> routes are configured, you need to remember or look up the convention.</p>\n<p>Being able to abandon a project for months or years and then come back to it is really important to me (that’s how all my projects work!), and Django feels easier to me because things are more explicit.</p>\n<p>In my small Django project it feels like I just have 5 main files (other than the settings files): <code>urls.py</code>, <code>models.py</code>, <code>views.py</code>, <code>admin.py</code>, and <code>tests.py</code>, and if I want to know where something else is (like an HTML template) is then it’s usually explicitly referenced from one of those files.</p>\n<h3><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#a-built-in-admin\">a built-in admin</a></h3>\n<p>For this project I wanted to have an admin interface to manually edit or view some of the data in the database. Django has a really nice built-in admin interface, and I can customize it with just a little bit of code.</p>\n<p>For example, here’s part of one of my admin classes, which sets up which fields to display in the “list” view, which field to search on, and how to order them by default.</p>\n<pre><code><span class=\"code-snippet\">@admin.register(Zine)\nclass ZineAdmin(admin.ModelAdmin):\n    list_display = [&quot;name&quot;, &quot;publication_date&quot;, &quot;free&quot;, &quot;slug&quot;, &quot;image_preview&quot;]\n    search_fields = [&quot;name&quot;, &quot;slug&quot;]\n    readonly_fields = [&quot;image_preview&quot;]\n    ordering = [&quot;-publication_date&quot;]\n</span></code></pre>\n<h3><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#it-s-fun-to-have-an-orm\">it’s fun to have an ORM</a></h3>\n<p>In the past my attitude has been “ORMs? Who needs them? I can just write my own SQL queries!”. I’ve been enjoying Django’s ORM so far though, and I think it’s cool how Django uses <code>__</code> to represent a <code>JOIN</code>, like this:</p>\n<pre><code><span class=\"code-snippet\">Zine.objects\n    .exclude(product__order__email_hash=email_hash)\n</span></code></pre>\n<p>This query involves 5 tables: <code>zines</code>, <code>zine_products</code>, <code>products</code>, <code>order_products</code>, and <code>orders</code>. To make this work I just had to tell Django that there’s a <code>ManyToManyField</code> relating “orders” and “products”, and another <code>ManyToManyField</code> relating “zines”, and “products”, so that it knows how to connect <code>zines</code>, <code>orders</code>, <code>products</code>.</p>\n<p>I definitely <em>could</em> write that query, but writing <code>product__order__email_hash</code> is a lot less typing, it feels a lot easier to read, and honestly I think it would take me a little while to figure out how to construct the query (which needs to do a few other things than just those joins).</p>\n<p>I have zero concern about the performance of my ORM-generated queries so I’m pretty excited about ORMs for now, though I’m sure I’ll find things to be frustrated with eventually.</p>\n<h3><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#automatic-migrations\">automatic migrations!</a></h3>\n<p>The other great thing about the ORM is migrations!</p>\n<p>If I add, delete, or change a field in <code>models.py</code>, Django will automatically generate a migration script like <code>migrations/0006_delete_imageblob.py</code>.</p>\n<p>I assume that I could edit those scripts if I wanted, but so far I’ve just been running the generated scripts with no change and it’s been going great. It really feels like magic.</p>\n<p>I’m realizing that being able to do migrations easily is important for me right now because I’m changing my data model fairly often as I figure out how I want it to work.</p>\n<h3><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#i-like-the-docs\">I like the docs</a></h3>\n<p>I had a bad habit of <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=krMw1QTP2no\">never reading the documentation</a> but I’ve been really enjoying the parts of Django’s docs that I’ve read so far. This isn’t by accident: Jacob Kaplan-Moss has a <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://pyvideo.org/pycon-us-2011/pycon-2011--writing-great-documentation.html\">talk from PyCon 2011</a> on Django’s documentation culture.</p>\n<p>For example the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://docs.djangoproject.com/en/6.0/topics/db/models/\">intro to models</a> lists the most important common fields you might want to set when using the ORM.</p>\n<h3><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#using-sqlite\">using sqlite</a></h3>\n<p>After having a bad experience trying to operate Postgres and not being able to understand what was going on, I decided to run all of my small websites with SQLite instead. It’s been going way better, and I love being able to backup by just doing a <code>VACUUM INTO</code> and then copying the resulting single file.</p>\n<p>I’ve been following <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://alldjango.com/articles/definitive-guide-to-using-django-sqlite-in-production\">these instructions</a> for using SQLite with Django in production.</p>\n<p>I think it should be fine because I’m expecting the site to have a few hundred writes per day at most, much less than <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://messwithdns.net/\">Mess with DNS</a> which has a lot more of writes and has been working well (though the writes are split across 3 different SQLite databases).</p>\n<h3><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#built-in-email-and-more\">built in email (and more)</a></h3>\n<p>Django seems to be very “batteries-included”, which I love – if I want CSRF protection, or a <code>Content-Security-Policy</code>, or I want to send email, it’s all in there!</p>\n<p>For example, I wanted to save the emails Django sends to a file in dev mode (so that it didn’t send real email to real people), which was just a little bit of configuration.</p>\n<p>I just put this <code>settings/dev.py</code>:</p>\n<pre><code><span class=\"code-snippet\">EMAIL_BACKEND = &quot;django.core.mail.backends.filebased.EmailBackend&quot;\nEMAIL_FILE_PATH = BASE_DIR / &quot;emails&quot;\n</span></code></pre>\n<p>and then set up the production email like this in <code>settings/production.py</code></p>\n<pre><code><span class=\"code-snippet\">EMAIL_BACKEND = &quot;django.core.mail.backends.smtp.EmailBackend&quot;\nEMAIL_HOST = &quot;smtp.whatever.com&quot;\nEMAIL_PORT = 587\nEMAIL_USE_TLS = True\nEMAIL_HOST_USER = &quot;xxxx&quot;\nEMAIL_HOST_PASSWORD = os.getenv(&#39;EMAIL_API_KEY&#39;)\n</span></code></pre>\n<p>That made me feel like if I want some other basic website feature, there’s likely to be an easy way to do it built into Django already.</p>\n<h3><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#the-settings-file-still-feels-like-a-lot\">the settings file still feels like a lot</a></h3>\n<p>I’m still a bit intimidated by the <code>settings.py</code> file: Django’s settings system works by setting a bunch of global variables in a file, and I feel a bit stressed about… what if I make a typo in the name of one of those variables? How will I know? What if I type <code>WSGI_APPLICATOIN = &quot;config.wsgi.application&quot;</code> instead of <code>WSGI_APPLICATION</code>?</p>\n<p>I guess I’ve gotten used to having a Python language server tell me when I’ve made a typo and so now it feels a bit disorienting when I can’t rely on the language server support.</p>\n<h3><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#that-s-all-for-now\">that’s all for now!</a></h3>\n<p>I haven’t really successfully used an actual web framework for a project before (right now almost all of my websites are either a single Go binary or static sites), so I’m interested in seeing how it goes!</p>\n<p>There’s still lots for me to learn about, I still haven’t really gotten into Django’s form validation tooling or authentication systems.</p>\n<p>Thanks to Marco Rogers for convincing me to give ORMs a chance.</p>\n<p>(we’re still experimenting with the comments-on-Mastodon system! <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://comments.jvns.ca/post/115969229107460589\">Here are the comments on Mastodon</a>! tell me your favourite Django feature!)</p>\n",
  "content_markdown": "Hello! One of my favourite things is starting to learn an Old Boring Technology that I’ve never tried before but that has been around for 20+ years. It feels really good when every problem I’m ever going to have has been solved already 1000 times and I can just get stuff done easily.\n\nI’ve thought it would be cool to learn a popular web framework like Rails or Django or Laravel for a long time, but I’d never really managed to make it happen. But I started learning Django to make a website a few months back, I’ve been liking it so far, and here are a few quick notes!\n\n### [less magic than Rails](https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#less-magic-than-rails)\n\nI spent some time [trying to learn Rails](https://jvns.ca/blog/2020/11/09/day-1--a-little-rails-/) in 2020, and while it was cool and I really wanted to like Rails (the Ruby community is great!), I found that if I left my Rails project alone for months, when I came back to it it was hard for me to remember how to get anything done because (for example) if it says `resources :topics` in your `routes.rb`, on its own that doesn’t tell you where the `topics` routes are configured, you need to remember or look up the convention.\n\nBeing able to abandon a project for months or years and then come back to it is really important to me (that’s how all my projects work!), and Django feels easier to me because things are more explicit.\n\nIn my small Django project it feels like I just have 5 main files (other than the settings files): `urls.py`, `models.py`, `views.py`, `admin.py`, and `tests.py`, and if I want to know where something else is (like an HTML template) is then it’s usually explicitly referenced from one of those files.\n\n### [a built-in admin](https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#a-built-in-admin)\n\nFor this project I wanted to have an admin interface to manually edit or view some of the data in the database. Django has a really nice built-in admin interface, and I can customize it with just a little bit of code.\n\nFor example, here’s part of one of my admin classes, which sets up which fields to display in the “list” view, which field to search on, and how to order them by default.\n\n```\n@admin.register(Zine)\nclass ZineAdmin(admin.ModelAdmin):\n    list_display = [\"name\", \"publication_date\", \"free\", \"slug\", \"image_preview\"]\n    search_fields = [\"name\", \"slug\"]\n    readonly_fields = [\"image_preview\"]\n    ordering = [\"-publication_date\"]\n```\n\n### [it’s fun to have an ORM](https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#it-s-fun-to-have-an-orm)\n\nIn the past my attitude has been “ORMs? Who needs them? I can just write my own SQL queries!”. I’ve been enjoying Django’s ORM so far though, and I think it’s cool how Django uses `__` to represent a `JOIN`, like this:\n\n```\nZine.objects\n    .exclude(product__order__email_hash=email_hash)\n```\n\nThis query involves 5 tables: `zines`, `zine_products`, `products`, `order_products`, and `orders`. To make this work I just had to tell Django that there’s a `ManyToManyField` relating “orders” and “products”, and another `ManyToManyField` relating “zines”, and “products”, so that it knows how to connect `zines`, `orders`, `products`.\n\nI definitely *could* write that query, but writing `product__order__email_hash` is a lot less typing, it feels a lot easier to read, and honestly I think it would take me a little while to figure out how to construct the query (which needs to do a few other things than just those joins).\n\nI have zero concern about the performance of my ORM-generated queries so I’m pretty excited about ORMs for now, though I’m sure I’ll find things to be frustrated with eventually.\n\n### [automatic migrations!](https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#automatic-migrations)\n\nThe other great thing about the ORM is migrations!\n\nIf I add, delete, or change a field in `models.py`, Django will automatically generate a migration script like `migrations/0006_delete_imageblob.py`.\n\nI assume that I could edit those scripts if I wanted, but so far I’ve just been running the generated scripts with no change and it’s been going great. It really feels like magic.\n\nI’m realizing that being able to do migrations easily is important for me right now because I’m changing my data model fairly often as I figure out how I want it to work.\n\n### [I like the docs](https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#i-like-the-docs)\n\nI had a bad habit of [never reading the documentation](https://www.youtube.com/watch?v=krMw1QTP2no) but I’ve been really enjoying the parts of Django’s docs that I’ve read so far. This isn’t by accident: Jacob Kaplan-Moss has a [talk from PyCon 2011](https://pyvideo.org/pycon-us-2011/pycon-2011--writing-great-documentation.html) on Django’s documentation culture.\n\nFor example the [intro to models](https://docs.djangoproject.com/en/6.0/topics/db/models/) lists the most important common fields you might want to set when using the ORM.\n\n### [using sqlite](https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#using-sqlite)\n\nAfter having a bad experience trying to operate Postgres and not being able to understand what was going on, I decided to run all of my small websites with SQLite instead. It’s been going way better, and I love being able to backup by just doing a `VACUUM INTO` and then copying the resulting single file.\n\nI’ve been following [these instructions](https://alldjango.com/articles/definitive-guide-to-using-django-sqlite-in-production) for using SQLite with Django in production.\n\nI think it should be fine because I’m expecting the site to have a few hundred writes per day at most, much less than [Mess with DNS](https://messwithdns.net/) which has a lot more of writes and has been working well (though the writes are split across 3 different SQLite databases).\n\n### [built in email (and more)](https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#built-in-email-and-more)\n\nDjango seems to be very “batteries-included”, which I love – if I want CSRF protection, or a `Content-Security-Policy`, or I want to send email, it’s all in there!\n\nFor example, I wanted to save the emails Django sends to a file in dev mode (so that it didn’t send real email to real people), which was just a little bit of configuration.\n\nI just put this `settings/dev.py`:\n\n```\nEMAIL_BACKEND = \"django.core.mail.backends.filebased.EmailBackend\"\nEMAIL_FILE_PATH = BASE_DIR / \"emails\"\n```\n\nand then set up the production email like this in `settings/production.py`\n\n```\nEMAIL_BACKEND = \"django.core.mail.backends.smtp.EmailBackend\"\nEMAIL_HOST = \"smtp.whatever.com\"\nEMAIL_PORT = 587\nEMAIL_USE_TLS = True\nEMAIL_HOST_USER = \"xxxx\"\nEMAIL_HOST_PASSWORD = os.getenv('EMAIL_API_KEY')\n```\n\nThat made me feel like if I want some other basic website feature, there’s likely to be an easy way to do it built into Django already.\n\n### [the settings file still feels like a lot](https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#the-settings-file-still-feels-like-a-lot)\n\nI’m still a bit intimidated by the `settings.py` file: Django’s settings system works by setting a bunch of global variables in a file, and I feel a bit stressed about… what if I make a typo in the name of one of those variables? How will I know? What if I type `WSGI_APPLICATOIN = \"config.wsgi.application\"` instead of `WSGI_APPLICATION`?\n\nI guess I’ve gotten used to having a Python language server tell me when I’ve made a typo and so now it feels a bit disorienting when I can’t rely on the language server support.\n\n### [that’s all for now!](https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/#that-s-all-for-now)\n\nI haven’t really successfully used an actual web framework for a project before (right now almost all of my websites are either a single Go binary or static sites), so I’m interested in seeing how it goes!\n\nThere’s still lots for me to learn about, I still haven’t really gotten into Django’s form validation tooling or authentication systems.\n\nThanks to Marco Rogers for convincing me to give ORMs a chance.\n\n(we’re still experimenting with the comments-on-Mastodon system! [Here are the comments on Mastodon](https://comments.jvns.ca/post/115969229107460589)! tell me your favourite Django feature!)\n",
  "dateCreated": "2026-09-19T21:30:23.395188495+00:00",
  "date_created": "2026-01-27T00:00:00+00:00",
  "date_modified": "2026-01-27T00:00:00+00:00",
  "date_published": "2026-01-27T00:00:00+00:00",
  "description": "Hello! One of my favourite things is starting to learn an Old Boring Technology that I’ve never tried before but that has been around for 20+ years. It feels really good when every problem I’m ever going to have has been solved already…",
  "external_url": "https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/",
  "git": {
    "commit": "ebb0941c5c06a2ab2377342d607535262a3e969e",
    "path": "items/jvns-ca/2026/01/2026-01-27-some-notes-on-starting-to-use-django.md",
    "permalink": "https://github.com/aymericbeaumet/aggr-instance/blob/ebb0941c5c06a2ab2377342d607535262a3e969e/items/jvns-ca/2026/01/2026-01-27-some-notes-on-starting-to-use-django.md"
  },
  "id": "urn:aggr:item:ae0452670d10237318b5a70edaf1cff8423ae98e",
  "isBasedOn": {
    "@id": "https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/"
  },
  "mainEntity": {
    "@id": "https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/",
    "@type": "CreativeWork",
    "archivedAt": {
      "@id": "https://aggr.aymericbeaumet.com/items/jvns-ca/2026-01-27-some-notes-on-starting-to-use-django/#webpage"
    },
    "dateModified": "2026-01-27T00:00:00+00:00",
    "datePublished": "2026-01-27T00:00:00+00:00",
    "headline": "Some notes on starting to use Django",
    "timeRequired": "PT6M",
    "url": "https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/",
    "wordCount": 1181
  },
  "name": "Archived snapshot: Some notes on starting to use Django",
  "preview": null,
  "reading_minutes": 6,
  "replicated_at": null,
  "source": "jvns-ca",
  "source_name": "Julia Evans",
  "summary": null,
  "tags": [],
  "temporalCoverage": "2026-09-19T21:30:23.395188495+00:00",
  "title": "Some notes on starting to use Django",
  "url": "https://aggr.aymericbeaumet.com/items/jvns-ca/2026-01-27-some-notes-on-starting-to-use-django/",
  "word_count": 1181
}