<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Cecilia Wambui</title>
    <description>The latest articles on DEV Community by Cecilia Wambui (@wambui_cecilia_685a751722).</description>
    <link>https://dev.to/wambui_cecilia_685a751722</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3930668%2F329db4ba-5270-4b8a-8e5f-b88eec17454f.png</url>
      <title>DEV Community: Cecilia Wambui</title>
      <link>https://dev.to/wambui_cecilia_685a751722</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wambui_cecilia_685a751722"/>
    <language>en</language>
    <item>
      <title>makemigrations vs migrate in Django: What’s the Difference?</title>
      <dc:creator>Cecilia Wambui</dc:creator>
      <pubDate>Fri, 24 Jul 2026 10:16:29 +0000</pubDate>
      <link>https://dev.to/wambui_cecilia_685a751722/makemigrations-vs-migrate-in-django-whats-the-difference-5ga6</link>
      <guid>https://dev.to/wambui_cecilia_685a751722/makemigrations-vs-migrate-in-django-whats-the-difference-5ga6</guid>
      <description>&lt;p&gt;If you’ve ever edited your models.py, stared at your database, and wondered why nothing actually changed, don't worry, almost everyone trips over Django migrations when starting out. The confusion usually comes down to one thing: Django doesn't touch your database when you edit Python code. Changing a model is just drafting an idea. To actually update the database, you have to run two separate commands, in a specific order.&lt;br&gt;
Here is what’s actually happening under the hood.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Mental Model
&lt;/h2&gt;

&lt;p&gt;Think of database changes in two stages: planning and executing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;models.py: Your blueprint. It defines what you want your data to look like in Python.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;makemigrations: The planner. It inspects models.py, compares it against your past migrations, and generates a new instruction file (a migration script). It does not touch your database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;migrate: The executor. It reads those instruction files and actually runs the SQL to create or update your database tables.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgbs30wan11nb9lxlogzt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgbs30wan11nb9lxlogzt.png" alt=" " width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  A Quick Code Example
&lt;/h2&gt;

&lt;p&gt;To see this in action, we'll use the Task model from our &lt;a href="https://youtu.be/SGj1lTigkAg" rel="noopener noreferrer"&gt;Django Beginner Tutorial on YouTube&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;TextField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;completed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;BooleanField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auto_now_add&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__str__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Editing this file is totally safe. You can add, tweak, or delete fields all day long, nothing breaks because Python hasn't talked to your database yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: makemigrations (Write the Plan)
&lt;/h2&gt;

&lt;p&gt;When you're ready to lock in your schema changes, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;python manage.py makemigrations
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Django checks your app’s migrations/ folder, notices your new Task model, and creates a file named something like 0001_initial.py.&lt;br&gt;
If you open that file, you’ll see Python code that describes the database operations needed to build that table.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmuedxjrnmdmxcapkoyus.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmuedxjrnmdmxcapkoyus.png" alt=" " width="799" height="468"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Why doesn't Django just update the database automatically?
&lt;/h2&gt;

&lt;p&gt;Keeping design separate from execution saves you from accidental disasters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sanity checks: You can look at the migration file before touching real data to ensure Django interpreted your changes correctly.&lt;/li&gt;
&lt;li&gt;Version control: Migration files live in Git alongside your code, meaning your teammates get the exact same database setup when they pull down your branch.&lt;/li&gt;
&lt;li&gt;Custom data fixes: If you need to transform or back up data before dropping a column, you can write custom logic inside the migration file first.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Step 2: migrate (Run the Plan)
&lt;/h2&gt;

&lt;p&gt;Once the migration file looks good, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;python manage.py migrate
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Django checks a special hidden table in your database called django_migrations. It looks for any migration files in your project that haven't been run yet, executes the corresponding SQL (CREATE TABLE, ALTER TABLE, etc.), and checks them off the list.&lt;br&gt;
Now your database schema matches your models.py.&lt;/p&gt;
&lt;h2&gt;
  
  
  The 2-Step Workflow in Action
&lt;/h2&gt;

&lt;p&gt;Let’s add a deadline field to our task model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# models.py
&lt;/span&gt;&lt;span class="n"&gt;deadline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Draft it: Run python manage.py makemigrations.
Django creates 0002_add_deadline.py with an AddField instruction.&lt;/li&gt;
&lt;li&gt;Apply it: Run python manage.py migrate.
Django connects to PostgreSQL/SQLite and executes the SQL statement to add the column.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Common Beginner Confusions
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;"I ran makemigrations, but my admin panel didn't change!" You wrote the plan, but didn't execute it. Run python manage.py migrate.&lt;/li&gt;
&lt;li&gt;"migrate says 'No migrations to apply', but I edited models.py!" You forgot to generate the plan. Run python manage.py makemigrations first.&lt;/li&gt;
&lt;li&gt;"Why do I have so many migration files?" Think of them like Git commits for your database schema. They record your project's database history step-by-step so you can replicate or roll back changes anytime.&lt;/li&gt;
&lt;li&gt;"Django asked me if I renamed a field, what do I do?" Pay attention to prompts like Did you rename task.due_date to task.deadline? [y/N]. If you hit "No", Django might delete the old column (and its data) and create a brand new empty one.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Practical Habits to Keep Your Database Safe
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Commit your migrations: Always check your migrations/ folder into Git. Never .gitignore it.&lt;/li&gt;
&lt;li&gt;Look before you leap: Skim auto-generated migration files before running migrate, especially in production.&lt;/li&gt;
&lt;li&gt;Deploy together: Pull your latest code to the server, then run python manage.py migrate as part of your deployment build script.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Once you get used to this two-step workflow, database migrations stop feeling like a chore and start working like a safety net. You design your models in Python, verify the plan, and apply the changes when you’re ready, no unexpected schema drops and no lost data.&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>programming</category>
      <category>django</category>
      <category>python</category>
    </item>
    <item>
      <title>Never Deploy Django Without These 6 Things</title>
      <dc:creator>Cecilia Wambui</dc:creator>
      <pubDate>Wed, 08 Jul 2026 06:28:12 +0000</pubDate>
      <link>https://dev.to/wambui_cecilia_685a751722/never-deploy-django-without-these-6-things-1hg0</link>
      <guid>https://dev.to/wambui_cecilia_685a751722/never-deploy-django-without-these-6-things-1hg0</guid>
      <description>&lt;p&gt;Deploying a Django app feels great, until something breaks in production.&lt;br&gt;
Everything may work locally, but once you deploy, you might run into missing styles, database errors, or an app that won’t start at all. That’s because Django’s default setup is built for development, not production.&lt;br&gt;
Before you deploy, make sure these six essentials are in place. If you are using Render, you also need an account there first, because that is where your app and database will be created and managed.&lt;/p&gt;
&lt;h2&gt;
  
  
  Prefer Watching Instead?
&lt;/h2&gt;

&lt;p&gt;If you’d rather see the full deployment process in action, I recorded a step-by-step walkthrough showing how to deploy a Django app to Render. You can watch it here: &lt;a href="https://youtu.be/6x9tUZhbNaY?si=JeCYyFzpHipWlV9b" rel="noopener noreferrer"&gt;https://youtu.be/6x9tUZhbNaY?si=JeCYyFzpHipWlV9b&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Gunicorn
&lt;/h2&gt;

&lt;p&gt;Django’s built-in runserver command is only for development. It is great for testing and debugging, but it is not meant for real traffic or production use. Gunicorn is the server that actually runs your Django app in production.&lt;br&gt;
Install it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;gunicorn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then add it to your requirements.txt and start your app with a command like this during deployment on Render:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gunicorn project_name.wsgi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Django builds the app. Gunicorn serves it.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. WhiteNoise
&lt;/h2&gt;

&lt;p&gt;In development, Django can find your static files through STATICFILES_DIRS.&lt;br&gt;
In production, that is not enough. WhiteNoise serves the collected static files from STATIC_ROOT, which is why it is so useful when deploying to Render.&lt;br&gt;
A simple setup looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;whitenoise
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the middleware:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;MIDDLEWARE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;django.middleware.security.SecurityMiddleware&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;whitenoise.middleware.WhiteNoiseMiddleware&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then define your static settings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;STATIC_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;static/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;STATICFILES_DIRS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;BASE_DIR&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;static&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;STATIC_ROOT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BASE_DIR&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;staticfiles&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are using a newer Django version, you should also configure STORAGES so Django knows how to handle static files properly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;STORAGES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;default&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BACKEND&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;django.core.files.storage.FileSystemStorage&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;staticfiles&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BACKEND&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;whitenoise.storage.CompressedManifestStaticFilesStorage&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This matters because STORAGES tells Django which storage backend to use.&lt;br&gt;
The staticfiles setting makes WhiteNoise manage your static assets correctly in production, including compression and versioned file names.&lt;br&gt;
So the flow is simple: STATICFILES_DIRS holds your source files, collectstatic gathers them into STATIC_ROOT, and WhiteNoise serves them from there in production.&lt;br&gt;
Finally, collect the files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python manage.py collectstatic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. psycopg
&lt;/h2&gt;

&lt;p&gt;SQLite is fine for development, but production usually needs PostgreSQL.&lt;br&gt;
To let Django talk to PostgreSQL, you need psycopg.&lt;br&gt;
Install it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;psycopg2-binary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without it, Django cannot connect to your production database on Render or any other hosting platform using PostgreSQL.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. dj-database-url
&lt;/h2&gt;

&lt;p&gt;Most hosting platforms give you one database connection string.&lt;br&gt;
Instead of breaking it apart manually, dj-database-url lets Django read it directly.&lt;br&gt;
Install it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;dj-database-url
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then use it like this in your settings.py:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;dj_database_url&lt;/span&gt;

&lt;span class="n"&gt;DATABASES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;default&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dj_database_url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It keeps your database setup clean and simple, especially when moving between local development and a Render production database.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. python-decouple
&lt;/h2&gt;

&lt;p&gt;Never hardcode things like your SECRET_KEY, database password, or API keys in your project.&lt;br&gt;
Those should live in environment variables instead.&lt;br&gt;
python-decouple makes that easy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;python-decouple
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then use it in your settings.py like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;decouple&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;

&lt;span class="n"&gt;SECRET_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SECRET_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;DEBUG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DEBUG&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cast&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This keeps sensitive data out of your code and makes deployment safer and easier to manage on Render.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. requirements.txt
&lt;/h2&gt;

&lt;p&gt;Your deployment platform starts with a fresh environment.&lt;br&gt;
It only knows what to install if you give it a requirements.txt file.&lt;br&gt;
Generate it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip freeze &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you forget to update it after adding packages, your deployment may fail because those packages won’t exist in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common mistakes to avoid
&lt;/h2&gt;

&lt;p&gt;Before deploying, double-check these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DEBUG=True is turned off.&lt;/li&gt;
&lt;li&gt;ALLOWED_HOSTS is set.&lt;/li&gt;
&lt;li&gt;collectstatic has been run.&lt;/li&gt;
&lt;li&gt;Migrations have been applied.&lt;/li&gt;
&lt;li&gt;Secrets are not hardcoded.&lt;/li&gt;
&lt;li&gt;requirements.txt is up to date.&lt;/li&gt;
&lt;li&gt;You have an active Render account before trying to deploy.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quick checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Gunicorn installed.&lt;/li&gt;
&lt;li&gt;WhiteNoise configured.&lt;/li&gt;
&lt;li&gt;PostgreSQL adapter installed.&lt;/li&gt;
&lt;li&gt;Database URL handled properly.&lt;/li&gt;
&lt;li&gt;Secrets stored safely.&lt;/li&gt;
&lt;li&gt;requirements.txt updated.&lt;/li&gt;
&lt;li&gt;Render account created and ready.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Deploying Django is not just about uploading code. It is about preparing your app for a production environment where security, performance, and reliability matter.&lt;br&gt;
If you understand these six things, deployment becomes much smoother and much less stressful. Render makes the hosting part easier, but your Django project still needs to be properly prepared before deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  About DevNook
&lt;/h2&gt;

&lt;p&gt;If you enjoy practical, beginner-friendly software development content, DevNook is built to help you become a better developer through real projects and clear explanations.&lt;br&gt;
You can continue learning here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/@dev-nook" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; for in-depth tutorials on Django, Python, React, JavaScript, APIs, deployment, Git, and more.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.getdevnook.com/" rel="noopener noreferrer"&gt;DevNook Website&lt;/a&gt; for step-by-step guides, articles, project walkthroughs, and learning resources.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/ceciliawambui" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; for source code and project examples used throughout tutorials.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading, and happy coding!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
