<?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>Forem: Farhan Masud Aneek</title>
    <description>The latest articles on Forem by Farhan Masud Aneek (@farhanmasud).</description>
    <link>https://forem.com/farhanmasud</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F676648%2F3a85e9bd-4b5c-4298-801f-82d3e16fbce7.jpeg</url>
      <title>Forem: Farhan Masud Aneek</title>
      <link>https://forem.com/farhanmasud</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/farhanmasud"/>
    <language>en</language>
    <item>
      <title>Setting up Django in a Better Way and Understanding How It Works</title>
      <dc:creator>Farhan Masud Aneek</dc:creator>
      <pubDate>Mon, 13 Nov 2023 18:36:28 +0000</pubDate>
      <link>https://forem.com/farhanmasud/setting-up-django-in-a-better-way-in-5-minutes-and-understanding-how-it-works-2lkg</link>
      <guid>https://forem.com/farhanmasud/setting-up-django-in-a-better-way-in-5-minutes-and-understanding-how-it-works-2lkg</guid>
      <description>&lt;p&gt;When you are setting up a new Django project, you'll have to configure quite a lot of things depending on the requirements of the project. Starting from database configurations to a custom user model, there are more than quite a few things to be done in between.&lt;/p&gt;

&lt;p&gt;There are very useful packages for bootstrapping your Django projects in minutes such as &lt;a href="https://github.com/cookiecutter/cookiecutter-django" rel="noopener noreferrer"&gt;django-cookiecutter&lt;/a&gt; and &lt;a href="https://github.com/wsvincent/djangox" rel="noopener noreferrer"&gt;djangox&lt;/a&gt;. If you are a seasoned developer, I'd highly recommend using one of these instead of what I'm going to show here. But if you are struggling with the project structure of these packages as a beginner to intermediate Django developer and looking to structure your own Django projects in a better way, I have created a lightweight setup that deals with the basics of setting up a Django project with PostgreSQL as database and TailwindCSS as our styling library.&lt;/p&gt;

&lt;p&gt;This &lt;a href="https://github.com/farhanmasud/django-tailwind-starter-template" rel="noopener noreferrer"&gt;Django Starter kit&lt;/a&gt; takes care of automated creation of virtual environment and installing of Python packages and setting up the database with bash scripts. In addition to PostgreSQL and TailwindCSS, all the sensitive values are taken care of in a .env file using &lt;a href="https://github.com/joke2k/django-environ" rel="noopener noreferrer"&gt;django-environ&lt;/a&gt; package. The virtual environment is maintained using &lt;a href="https://github.com/jazzband/pip-tools" rel="noopener noreferrer"&gt;pip-tools&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The static files are managed with &lt;a href="https://whitenoise.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;whitenoise&lt;/a&gt;, &lt;a href="https://gunicorn.org/" rel="noopener noreferrer"&gt;Gunicorn&lt;/a&gt; is used for the WSGI server and &lt;a href="https://sentry.io/welcome/" rel="noopener noreferrer"&gt;Sentry&lt;/a&gt; is used for error monitoring and reporting in production.&lt;/p&gt;

&lt;p&gt;Since the scripts are in bash, these will only run on UNIX based operating systems like Linux and MacOS. But you can also run this on Windows with &lt;a href="https://git-scm.com/downloads" rel="noopener noreferrer"&gt;Git Bash&lt;/a&gt; or &lt;a href="https://ubuntu.com/tutorials/install-ubuntu-on-wsl2-on-windows-10#1-overview" rel="noopener noreferrer"&gt;WSL&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before getting started
&lt;/h2&gt;

&lt;p&gt;Make sure you have &lt;a href="https://www.postgresql.org/docs/current/installation.html" rel="noopener noreferrer"&gt;PostgreSQL&lt;/a&gt; and &lt;a href="https://nodejs.org/en/download/package-manager#nvm" rel="noopener noreferrer"&gt;Node.js + npm&lt;/a&gt; installed on your local machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Setup
&lt;/h2&gt;

&lt;p&gt;Here are the steps to setup this starter kit. Setting this up shouldn't take more than 5 minutes. I'm going to explain all the steps in detail and how it's configured on the later sections so that you have in depth understanding about how this works under the hood (which will take way longer than 5 minutes but I can assure that it's worth the time). By understanding the structure of the project from the later sections, you can create something on your own that suits your needs best.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Clone repo with your project name &lt;code&gt;git clone git@github.com:farhanmasud/django-tailwind-starter-template.git your-project-name&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Setup .env file following the example env file &lt;code&gt;example.env&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Make all bash scripts executable with &lt;code&gt;find . -type f -iname "*.sh" -exec chmod +x {} \;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;bash update-git-remote.sh&lt;/code&gt; script to remove existing git remote link (of this repo) and update with your on git repo link. Copy your remote URL from GitHub and run the bash script, it'll prompt to enter the new link. Paste your new link and hit Enter.&lt;/li&gt;
&lt;li&gt;Setup database [requires step 2] with &lt;code&gt;bash setup-db.sh&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Setup venv and install dependencies with &lt;code&gt;bash setup-venv-pip-tools.sh&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Activate virtual environment with &lt;code&gt;source venv/bin/activate&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Install tailwind dependencies with &lt;code&gt;python manage.py tailwind install&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Run migrations with &lt;code&gt;python manage.py migrate&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Collect static &lt;code&gt;python manage.py collectstatic --no-input&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Setup Explanation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Cloning the repository
&lt;/h3&gt;

&lt;p&gt;First, clone &lt;a href="https://github.com/farhanmasud/django-tailwind-starter-template" rel="noopener noreferrer"&gt;this repository&lt;/a&gt; on your local with &lt;code&gt;git clone git@github.com:farhanmasud/django-tailwind-starter-template.git your-project-name&lt;/code&gt; command. If you are going to call this project &lt;code&gt;quick-django-project&lt;/code&gt;, the command will be  -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone git@github.com:farhanmasud/django-tailwind-starter-template.git quick-django-project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Updating the &lt;code&gt;.env&lt;/code&gt; file
&lt;/h3&gt;

&lt;p&gt;Navigate to this newly created &lt;code&gt;quick-django-project&lt;/code&gt; directory and copy the &lt;code&gt;.example.env&lt;/code&gt; and paste with the name &lt;code&gt;.env&lt;/code&gt; in the same directory.&lt;/p&gt;

&lt;p&gt;Open the &lt;code&gt;.env&lt;/code&gt; file and update the environment variables as follows.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;WORK_ENV=local&lt;/code&gt; Since we have different settings file for different environment such as production, testing, staging and local development. We're updating this to &lt;code&gt;local&lt;/code&gt; to make sure only packages needed for local development packages are installed and only settings that are intended for the local development environment is loaded.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generate a secret key for Django and update the &lt;code&gt;SECRET_KEY&lt;/code&gt; variable. You can generate Django secret key by following this question from &lt;a href="https://stackoverflow.com/questions/41298963/is-there-a-function-for-generating-settings-secret-key-in-django" rel="noopener noreferrer"&gt;StackOverflow&lt;/a&gt; or use this &lt;a href="https://djecrety.ir/" rel="noopener noreferrer"&gt;web UI&lt;/a&gt;. Let's say our generated secret key is &lt;code&gt;@6jc16lc(+mhjnkfk@^)46xc728u0j&amp;amp;(z)y!qkimo4b#ggnos7&lt;/code&gt; and in our environment file, it'll be &lt;code&gt;SECRET_KEY=@6jc16lc(+mhjnkfk@^)46xc728u0j&amp;amp;(z)y!qkimo4b#ggnos7&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set &lt;code&gt;ALLOWED_HOSTS=localhost,127.0.0.1&lt;/code&gt; which will allow us to access our Django project on local machine with localhost or 127.0.0.1.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Grab the password for the user &lt;code&gt;postgres&lt;/code&gt; on PostgreSQL and use with &lt;code&gt;PGPASSWORD&lt;/code&gt; variable. If your password is &lt;code&gt;examplepostgrespassword1234&lt;/code&gt; set &lt;code&gt;PGPASSWORD=examplepostgrespassword1234&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set your database name, database password and database user as your preference.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;DB_NAME=django_project&lt;/code&gt;&lt;br&gt;
&lt;code&gt;DB_USER=django_user&lt;/code&gt;&lt;br&gt;
&lt;code&gt;DB_PASSWORD=exampledatabasepassword1234&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And keep the following as is -&lt;/p&gt;

&lt;p&gt;&lt;code&gt;DB_HOST=localhost&lt;/code&gt;&lt;br&gt;
&lt;code&gt;DB_PORT=5432&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Create an account on &lt;a href="https://sentry.io/welcome/" rel="noopener noreferrer"&gt;Sentry&lt;/a&gt; and create a project for Django. You can follow the steps on &lt;a href="https://docs.sentry.io/platforms/python/integrations/django/#configure" rel="noopener noreferrer"&gt;Sentry documentation for Django&lt;/a&gt; to get your dsn link and update the &lt;code&gt;SENTRY_DSN&lt;/code&gt; variable. Enter the value without quotes here.&lt;br&gt;
&lt;code&gt;SENTRY_DSN=https://examplePublicKey@o0.ingest.sentry.io/0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Setting up the &lt;code&gt;.env&lt;/code&gt; file is done. Now let's use these environment variables to setup our Django project.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Making the helper bash files executable and running the bash files
&lt;/h3&gt;

&lt;p&gt;There are 4 bash scripts in this starter kit -&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;setup-db.sh&lt;/code&gt; script is for setting up the database for our Django project with PostgreSQL&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;setup-venv-pip-tools.sh&lt;/code&gt; script is for setting up the virtual environment using &lt;code&gt;pip-tools&lt;/code&gt; and installing the packages.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pip-tools&lt;/code&gt; require a few commands to compile and then install a new package. &lt;code&gt;pip-install.sh&lt;/code&gt; script runs these commands one by one.&lt;/li&gt;
&lt;li&gt;For updating the git origin, you can use &lt;code&gt;update-git-remote.sh&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To make these bash script, open your terminal, navigate to the project directory and run &lt;code&gt;find . -type f -iname "*.sh" -exec chmod +x {} \;&lt;br&gt;
Run bash update-git-remote.sh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now the bash scripts are ready to run.&lt;/p&gt;

&lt;p&gt;To start, create a new repository on &lt;a href="https://github.com/" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and create an empty repository. Copy the git remote origin link and on your terminal, inside your project directory, run &lt;code&gt;bash update-git-remote.sh&lt;/code&gt;. This will prompt you to enter your git remote origin link, just paste it here with &lt;code&gt;CTRL + Shift + V&lt;/code&gt; or &lt;code&gt;CMD + Shift + V&lt;/code&gt; and press &lt;code&gt;Enter&lt;/code&gt;. Your project is now linked with your GitHub repository.&lt;/p&gt;
&lt;h3&gt;
  
  
  4. Setting up the Database
&lt;/h3&gt;

&lt;p&gt;We're going to use PostgreSQL for the database here. We'll need to setup the PostgreSQL database and user and tell Django the database, user and user password so that Django can connect to the database. For both of the purposes we'll just update the &lt;code&gt;.env&lt;/code&gt; file with the variables (we've already done this on step 2) and run the &lt;code&gt;setup-db.sh&lt;/code&gt; bash script.&lt;/p&gt;

&lt;p&gt;Similar to running other bash scripts, open up the terminal, navigate to your project directory and run &lt;code&gt;bash setup-db.sh&lt;/code&gt; which will ask for your sudo password of your current user. Press enter after entering the password and the script will setup the database.&lt;/p&gt;
&lt;h3&gt;
  
  
  5. Setting up the Virtual Environment
&lt;/h3&gt;

&lt;p&gt;This repository has all the packages that you'll need to get up and running with PostgreSQL, Tailwind, managing environment variables, managing static files and so on. To install this package in a virtual environment, this package uses &lt;a href="https://github.com/jazzband/pip-tools" rel="noopener noreferrer"&gt;pip-tools&lt;/a&gt;. &lt;code&gt;pip-tools&lt;/code&gt; requires a couple of commands to collect, compile and install the packages that you need. We have a bash script to create our virtual environment and run all of the commands one by one.&lt;/p&gt;

&lt;p&gt;Open your terminal and navigate to your project directory and run &lt;code&gt;bash setup-venv-pip-tools.sh&lt;/code&gt;. This will prompt you to enter if you are in development environment or in production. Enter &lt;code&gt;D&lt;/code&gt; if you are in development environment or enter &lt;code&gt;P&lt;/code&gt; if you are in production environment and press Enter on your keyboard. This will create a virtual environment called &lt;code&gt;venv&lt;/code&gt;, install &lt;code&gt;pip-tools&lt;/code&gt; and install all the packages required for your development or production environment.&lt;/p&gt;
&lt;h3&gt;
  
  
  6. Adding further packages
&lt;/h3&gt;

&lt;p&gt;The existing packages in this repository are for getting the Django project up and running only. You'll definitely need a lot more packages while developing the project. The packages are kept within the &lt;code&gt;.in&lt;/code&gt; files inside the &lt;code&gt;requirements&lt;/code&gt; directory. You'll find three files in the directory -&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;requirements.in&lt;/code&gt; for packages that will be used both in local and production such as django itself.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;requirements-dev.in&lt;/code&gt; for packages that will only be used in development such as &lt;a href="https://django-debug-toolbar.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;django-debug-toolbar&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;requirements-prod.in&lt;/code&gt; for packages that will only be used in production such as &lt;a href="https://gunicorn.org/" rel="noopener noreferrer"&gt;Gunicorn&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When you need to add a new package, figure out where the package will be used and and the package there.&lt;/p&gt;

&lt;p&gt;Then run the &lt;code&gt;pip-install.sh&lt;/code&gt; bash script using &lt;code&gt;bash pip-install.sh&lt;/code&gt; command, enter &lt;code&gt;D&lt;/code&gt; if you are on your local environment or enter &lt;code&gt;P&lt;/code&gt; if you are on your production environment. This will automatically compile the packages and dependencies and install them in the virtual environment.&lt;/p&gt;
&lt;h3&gt;
  
  
  7. Installing Tailwind
&lt;/h3&gt;

&lt;p&gt;Most of our installation is done but we haven't configured Tailwind yet. &lt;a href="https://github.com/timonweb/django-tailwind" rel="noopener noreferrer"&gt;django-tailwind&lt;/a&gt; is already installed with the required Python packages but we'll need to compile this to fully setup Tailwind and make it ready to work in our local development environment.&lt;/p&gt;

&lt;p&gt;To finish the Tailwind configuration, activate the virtual environment that we have created with &lt;code&gt;source venv/bin/activate&lt;/code&gt; and run &lt;code&gt;python manage.py tailwind install&lt;/code&gt; to complete the installation. You must have &lt;code&gt;Node.js&lt;/code&gt; and &lt;code&gt;npm&lt;/code&gt; installed for this to work.&lt;/p&gt;

&lt;p&gt;You'll see a Django app in the project directory called &lt;code&gt;theme&lt;/code&gt; and this is the app for Tailwind. Inside this you'll find the &lt;code&gt;static_src&amp;gt;tailwind.config.js&lt;/code&gt; where you can configure Tailwind as per your requirements. You'll also see there is a base template (&lt;code&gt;theme/templates/base.html&lt;/code&gt;) which is provided by the &lt;code&gt;django-tailwind&lt;/code&gt; package. You can use this or make your own following the conventions shown here for loading tailwind. First, you'll have to load the tailwind template tags with &lt;code&gt;{% load tailwind_tags %}&lt;/code&gt; at the top of your html file and use &lt;code&gt;{% tailwind_css %}&lt;/code&gt; to load the CSS files into the head of your html.&lt;/p&gt;
&lt;h3&gt;
  
  
  8. Running Migrations
&lt;/h3&gt;

&lt;p&gt;You are probably aware that Django recommends setting up a custom user model for your project before you do any migrations. This starter kit comes with a custom user model that uses &lt;code&gt;email&lt;/code&gt; instead of the default &lt;code&gt;username&lt;/code&gt; field. The migrations are already made in the &lt;code&gt;accounts&lt;/code&gt; app and there you'll find the custom user model &lt;code&gt;Account&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now we just have to apply these migrations to our database including all other default migrations that Django comes with. With virtual environment activated, run the command &lt;code&gt;python manage.py migrate&lt;/code&gt; to apply the migrations.&lt;/p&gt;
&lt;h3&gt;
  
  
  9. Managing Static files
&lt;/h3&gt;

&lt;p&gt;We have some static files coming from the Tailwind package. In your development environment, these will be automatically available when you start the development server. But in production, you'll need to collect the static files using &lt;code&gt;python manage.py collectstatic&lt;/code&gt; command.&lt;/p&gt;
&lt;h3&gt;
  
  
  10. Run the development server!
&lt;/h3&gt;

&lt;p&gt;Okay, we are done setting the Django project! With virtual environment activated, run &lt;code&gt;python manage.py runserver&lt;/code&gt; and the development server will run on the default port 8000 on your localhost. If go to &lt;code&gt;localhost:8000&lt;/code&gt; from your browser, you'll see a &lt;code&gt;404 Not Found&lt;/code&gt; error. But don't worry, this is intentional. This starter kit doesn't come with extra app or template that you'll not need later. Just create your app from here, configure urls and start building models and views as you want.&lt;/p&gt;
&lt;h2&gt;
  
  
  Structure of the project
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Splitting the settings.py file
&lt;/h3&gt;

&lt;p&gt;When you create a new Django project, you'll find a &lt;code&gt;settings.py&lt;/code&gt; file inside your project directory that holds all the settings file related to your Django Project. But in this starter kit, you'll see that there is a directory called &lt;code&gt;config&lt;/code&gt; and inside this there is a directory called &lt;code&gt;settings&lt;/code&gt;. Inside this directory you'll find multiple settings files - &lt;code&gt;base.py&lt;/code&gt;, &lt;code&gt;local.py&lt;/code&gt;, &lt;code&gt;test.py&lt;/code&gt;, &lt;code&gt;staging.py&lt;/code&gt;, &lt;code&gt;production.py&lt;/code&gt; and &lt;code&gt;engage.py&lt;/code&gt;. The &lt;code&gt;base.py&lt;/code&gt; settings file holds all the settings that are applicable no matter which environment your project your running. &lt;code&gt;local.py&lt;/code&gt;, &lt;code&gt;test.py&lt;/code&gt;, &lt;code&gt;staging.py&lt;/code&gt; and &lt;code&gt;production.py&lt;/code&gt; files contain all the settings related to Local, testing, staging and production environment. Finally, the &lt;code&gt;engage.py&lt;/code&gt; file dynamically loads the settings from &lt;code&gt;local.py&lt;/code&gt;, &lt;code&gt;test.py&lt;/code&gt;, &lt;code&gt;staging.py&lt;/code&gt; and &lt;code&gt;production.py&lt;/code&gt; based on what you have provided on the &lt;code&gt;WORK_ENV&lt;/code&gt; variable in the &lt;code&gt;.env&lt;/code&gt; file and combines the settings with &lt;code&gt;base.py&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The reason behind this splitting is that we can safely use packages and related settings only where we need. For example, this starter kit has the package &lt;a href="https://github.com/jazzband/django-debug-toolbar" rel="noopener noreferrer"&gt;django-debug-toolbar&lt;/a&gt;. This is only intended for your development environment and not for your production. This can be very risky if used in production because if your Django project encounters errors, all the debug info will be shown to the user which is a severe security risk. Similarly, for tracking errors in production, we're using Sentry which is not needed in our local environment since we already have &lt;code&gt;django-debug-toolbar&lt;/code&gt;. For keeping these settings file separate so that they don't conflict with each other, the settings file is split for serving different environments.&lt;/p&gt;
&lt;h3&gt;
  
  
  Keeping sensitive data out of the codebase (and version control system)
&lt;/h3&gt;

&lt;p&gt;Data like &lt;code&gt;SECRET_KEY&lt;/code&gt; or your database connection details are sensitive and can cause serious security issues if they are not protected. If you keep these (along with other sensitive data like API keys)  in your &lt;code&gt;settings.py&lt;/code&gt; file and commit them in your version control system such as Git, your project can be at risk in production.&lt;/p&gt;

&lt;p&gt;To protect these data, it's best to keep this in a separate &lt;code&gt;.env&lt;/code&gt; file and keeping it out of the version control system. In this starter kit, we are using &lt;a href="https://django-environ.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;django-environ&lt;/a&gt; to achieve this. For example, you can see in &lt;code&gt;config/settings/base.py&lt;/code&gt;, we are reading the &lt;code&gt;SECRET_KEY&lt;/code&gt; with &lt;code&gt;django-environ&lt;/code&gt; as &lt;code&gt;SECRET_KEY = env("SECRET_KEY")&lt;/code&gt; where we have a variable named &lt;code&gt;SECRET_KEY&lt;/code&gt; in our &lt;code&gt;.env&lt;/code&gt; file. Obviously, we have to import &lt;code&gt;django-environ&lt;/code&gt; and the python &lt;code&gt;os&lt;/code&gt; package with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import environ
import os
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and configure it with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;env = environ.Env()
env.read_env(os.path.join(BASE_DIR, ".env"))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure that your &lt;code&gt;.env&lt;/code&gt; file lives at the root of the project directory and you are good to go.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using pip-tools
&lt;/h3&gt;

&lt;p&gt;When you are working on a Python project, it's best to pin your Python packages in a separate &lt;code&gt;requirements.txt&lt;/code&gt; file with the exact version pinned and install them in a virtual environment. Python &lt;a href="https://docs.python.org/3/library/venv.html" rel="noopener noreferrer"&gt;venv&lt;/a&gt; is probably the most popular choice due to it's very easy setup process. Keeping required packages pinned with versions helps in many ways. For example maybe you were working on a project 2 years back and you were using a package that had the version 1.0.0 at that time. Now after 2 years, that package might have been updated to version 3.0.0. If you try to install the version 3.0.0 and try to run your project, there is high chance it won't work because it has changed.&lt;/p&gt;

&lt;p&gt;Similarly, if you have that old project that used the package version 1.0.0 and you installed the package globally and try to start a new project with the same package and use version 3.0.0, only one of them will work. If you install version 3.0.0, the one that uses version 1.0.0 won't work and vice-versa.&lt;/p&gt;

&lt;p&gt;Python virtual environments solve this issue. You can create virtual environments with &lt;code&gt;venv&lt;/code&gt; and keep a simple &lt;code&gt;requirements.txt&lt;/code&gt; file with packages and version information that's required in your project. And you can install them in the virtual environment independently so that they don't affect other projects.&lt;/p&gt;

&lt;p&gt;Instead of &lt;code&gt;venv&lt;/code&gt;, we are using &lt;code&gt;pip-tools&lt;/code&gt; in this starter kit. &lt;code&gt;pip-tools&lt;/code&gt; take things further in dependency management. Check out &lt;a href="https://github.com/jazzband/pip-tools" rel="noopener noreferrer"&gt;what pip-tools does&lt;/a&gt; in their official GitHub repo. In short, it helps your project find the best match for the dependent packages. For example, you might need two packages &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; in your project that requires same package &lt;code&gt;C&lt;/code&gt; under the hood. But &lt;code&gt;A&lt;/code&gt; requires any version of &lt;code&gt;C&lt;/code&gt; from 1.0.1 to 1.0.10 and &lt;code&gt;B&lt;/code&gt; requires any version of &lt;code&gt;C&lt;/code&gt; from 1.0.7 to 1.0.15. Pip tools will automatically compile the version of 'C' that suits for both of your packages.&lt;/p&gt;

&lt;p&gt;To keep all the requirements, you'll find a &lt;code&gt;requirements&lt;/code&gt; directory in the project. There will be 3 files (two more after they are compiled but we don't keep that in the version control) - &lt;code&gt;requirements.in&lt;/code&gt;, &lt;code&gt;requirements-dev.in&lt;/code&gt; and &lt;code&gt;requirements-prod.in&lt;/code&gt;. The idea here is similar how are splitting the &lt;code&gt;settings.py&lt;/code&gt; file. We are only keeping the packages that are relevant to the related environment. So when you setup the virtual environment with &lt;code&gt;bash setup-venv-pip-tools.sh&lt;/code&gt; or install the packages with &lt;code&gt;bash pip-install.sh&lt;/code&gt;, you are prompted to enter your choice between development and production environments and with that the bash script compiles the packages with &lt;code&gt;pip-tools&lt;/code&gt; from the &lt;code&gt;requirements.in&lt;/code&gt; file as the base and from &lt;code&gt;requirements-dev.in&lt;/code&gt; or &lt;code&gt;requirements-prod.in&lt;/code&gt; as per your choice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Custom User Model
&lt;/h3&gt;

&lt;p&gt;As Django recommends, we are using a custom user model that you can find as &lt;code&gt;Account&lt;/code&gt; model in &lt;code&gt;accounts/models.py&lt;/code&gt;. Here we are using the user's email field as the unique identifier instead of the default username. We are also using a custom manager for managing the objects. And in &lt;code&gt;accounts/admin.py&lt;/code&gt;, the &lt;code&gt;Account&lt;/code&gt; model is made compatible with the Django admin so that you can add users from the Django admin.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finally, Bash Scripts
&lt;/h3&gt;

&lt;p&gt;What we have done setting up the Django project with this starter kit is updating the &lt;code&gt;.env&lt;/code&gt; file and running some bash scripts. Bash is a fun scripting tool for UNIX based systems (although it can vary sometime from different UNIX based systems). What is done in the scripts is just telling the computer to run a series of related commands one after another. Bash scripting is a lot of fun (and frustrating) as you can automate many of your workflows with this. If you are interested, you can &lt;a href="https://www.freecodecamp.org/news/bash-scripting-tutorial-linux-shell-script-and-command-line-for-beginners/" rel="noopener noreferrer"&gt;start learning bash scripting&lt;/a&gt; from here.&lt;/p&gt;

&lt;p&gt;Well, that's pretty much all. Ended up longer than I had expected even after skipping some details I initially wanted to include. But I hope it helps you give a good insight about structuring a Django project. If you examine the repository on Github, you can get a better idea of what's actually going on which is actually very simple. And from there you can explore &lt;a href="https://github.com/cookiecutter/cookiecutter-django" rel="noopener noreferrer"&gt;django-cookiecutter&lt;/a&gt; and &lt;a href="https://github.com/wsvincent/djangox" rel="noopener noreferrer"&gt;djangox&lt;/a&gt; to see what suits your needs best and might even create something that works the best for you.&lt;/p&gt;

</description>
      <category>django</category>
      <category>python</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Developing Maintainable Django Projects for the Long Run</title>
      <dc:creator>Farhan Masud Aneek</dc:creator>
      <pubDate>Sun, 01 Aug 2021 22:21:43 +0000</pubDate>
      <link>https://forem.com/farhanmasud/developing-maintainable-django-projects-for-the-long-run-knb</link>
      <guid>https://forem.com/farhanmasud/developing-maintainable-django-projects-for-the-long-run-knb</guid>
      <description>&lt;p&gt;Django being the web framework for the perfectionists definitely comes with many handy features out of the box. Even after being a very opinionated framework [there is always the "Django way" for doing things], in many cases there are more than a few ways to do the same thing. This might lead to some poor structure and coding choices for many beginners as described in &lt;a href="https://www.toptal.com/django/django-top-10-mistakes"&gt;this blog post&lt;/a&gt;. These mistakes [along with many others] often lead to unmanageable code in the long run when the size of the project keeps growing.&lt;/p&gt;

&lt;p&gt;If there is a bug and causes downtime in production then fixing the error might feel like finding a needle in the haystack with a poorly structured codebase. The above mentioned link can work as a style guide [like many other, scroll to the end of this blog post for more Django style guides] for structuring Django projects which can help manage our code better. On top of this, let's dive into 11 ways that will definitely make life easier developing and maintaining a Django project for the long run.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Code Formatting and Linting
&lt;/h2&gt;

&lt;p&gt;The codebase should be clean, concise and readable as suggested by the &lt;a href="https://django-best-practices.readthedocs.io/en/latest/code.html"&gt;Django Best Practices&lt;/a&gt; guide. To maintain such a codebase, the best approach is to follow a specific code style and format. The hard part is remembering all the formatting rules and getting every developer working on the project onboard with these specific rules. That can eat up a lot of unnecessary time in development.&lt;/p&gt;

&lt;p&gt;Enter &lt;a href="https://github.com/psf/black"&gt;black&lt;/a&gt; - The Uncompromising Code Formatter. It supports all major IDEs and upon saving a file, it does it's black magic to convert all the messy code to beautifully structured code. You can also run black against your whole codebase for formatting all of the files as well. Here is a &lt;a href="https://dev.to/adamlombard/how-to-use-the-black-python-code-formatter-in-vscode-3lo0"&gt;handy guide on dev.to&lt;/a&gt; for setting up black in VSCode.&lt;/p&gt;

&lt;p&gt;To help you with syntax errors, &lt;a href="https://github.com/PyCQA/pylint"&gt;pylint&lt;/a&gt; is an amazing tool. There is also a dedicated Django extension for pylint called &lt;a href="https://github.com/PyCQA/pylint-django"&gt;pylint-django&lt;/a&gt;. Pylint is the default linter in VSCode and you can setup pylint-django just by installing it via pip and updating the settings as shown on &lt;a href="https://code.visualstudio.com/docs/python/linting#:~:text=Pylint%20plugins%2C%20such,load-plugins%22%2C%20%22pylint_django%22%5D"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Finally, to help you code even faster, you can use &lt;a href="https://www.kite.com/"&gt;Kite&lt;/a&gt; for AI powered auto-completion.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Environment Variables and Django Settings File
&lt;/h2&gt;

&lt;p&gt;Your environment variables like &lt;code&gt;SECRET_KEY&lt;/code&gt; or anything related to database setup should never be placed directly in the Django settings file and in the version control. These are sensitive data and you should safely keep them out of anyone's reach who's not supposed to see it.&lt;/p&gt;

&lt;p&gt;You can use &lt;a href="https://github.com/joke2k/django-environ"&gt;django-environ&lt;/a&gt; for serving the purpose. The process is very straightforward as well. You just need to create an &lt;code&gt;.env&lt;/code&gt; file and keep all your variables there and import them into your settings file using the API of django-environ package. And keep this &lt;code&gt;.env&lt;/code&gt; file out of version by placing it in the &lt;code&gt;.gitignore&lt;/code&gt; file. But you should keep an &lt;code&gt;.env.example&lt;/code&gt; file in the version control that contains a template of the original &lt;code&gt;.env&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Your development coding environment will obviously differ in one way or another and to match with that, your project's settings file will differ as well. If you are keeping your development settings in the old fashioned &lt;code&gt;local_settings.py&lt;/code&gt; file and keeping out of version control, you are probably doing it wrong and there are many &lt;a href="https://daniel.feldroy.com/posts/using-executable-code-outside-version-control"&gt;valid reasons for that&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A better approach is to split up your settings file into base, development, test, stage and production files along with a &lt;code&gt;__init__.py&lt;/code&gt; file that will go to a settings directory replacing the &lt;code&gt;settings.py&lt;/code&gt; file. The &lt;code&gt;base.py&lt;/code&gt; settings file will hold all the settings that don't need to change and the development, test, stage and production settings files containing all the environment specific settings with start with importing all the settings from the &lt;code&gt;base.py&lt;/code&gt; file as &lt;code&gt;from .base import *&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;One issue that will come up with this approach is that the &lt;code&gt;manage.py&lt;/code&gt; will be pointing to the older settings file and it'll no longer work. In this case you won't be able to run your development server along with any commands with &lt;code&gt;manage.py&lt;/code&gt;. To solve this, you can create a new environment variable called &lt;code&gt;WORK_ENV&lt;/code&gt; in your &lt;code&gt;.env&lt;/code&gt; file and a new &lt;code&gt;engage.py&lt;/code&gt; file in the settings directory which will contain -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from .base import *

working_environment = env.str("WORK_ENV", default="development")


if working_environment == "production":
    from .production import *
elif working_environment == "stage":
    from .stage import *
elif working_environment == "test":
    from .test import *
else:
    from .development import *
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally, update your manage.py file to replace the line&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'your_project.settings')&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;with&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;os.environ.setdefault("DJANGO_SETTINGS_MODULE", "your_project.settings.engage")&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;So, previously all the settings with all sensitive information would have been stored in a single &lt;code&gt;settings.py&lt;/code&gt; file. And now, with the split up settings file and the &lt;code&gt;.env&lt;/code&gt; file, it should look like -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|--settings
   |-- __init__.py
   |-- base.py
   |-- engage.py
   |-- development.py
   |-- production.py
   |-- stage.py
   |-- test.py
   |-- .env
   |-- .env.example
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. PostgreSQL Everywhere
&lt;/h2&gt;

&lt;p&gt;Django comes with a simple and lightweight SQLite3 database out of the box which takes you out of the hassle of setting up the database and you can go straight to developing your application. But there are many cases where it might go wrong and even restrict you from writing efficient code for filtering your data from the database. Among others, one example can be how to filter distinct values as explained &lt;a href="https://stackoverflow.com/questions/4723220/retrieving-distinct-records-based-on-a-column-on-django#comment23664405_4725945"&gt;here&lt;/a&gt;, you can't really use the SQLite3 database for this.&lt;/p&gt;

&lt;p&gt;PostgreSQL database works fantastic with Django. It is &lt;a href="https://djangodeployment.com/2016/12/23/which-database-should-i-use-on-production/"&gt;recommended&lt;/a&gt; by many to use PostgreSQL in production. A better approach would be using it in all of your environments [development, test, stage and production] so that your application works consistently everywhere. If you can just go through the setting up the PostgreSQL database on your environments [just a few commands anyway and if you use Docker you can streamline the process even further], you don't have to spend time thinking about which Django ORM features that you can use.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. API Documentation
&lt;/h2&gt;

&lt;p&gt;If you are working with Django REST framework, it's a good idea to keep your API documented even if you are not exposing it to the public. One great tool is &lt;a href="https://swagger.io/"&gt;Swagger&lt;/a&gt; and you can generate the Swagger schema automatically for your DRF project by using &lt;a href="https://github.com/axnsan12/drf-yasg"&gt;drf-yasg&lt;/a&gt;. Very easy to setup and the schema will be generated from your &lt;code&gt;urls.py&lt;/code&gt; files. You can also choose between two different looks.&lt;/p&gt;

&lt;p&gt;Keep in mind that drf-yasg generates Swagger/OpenAPI 2.0 specification of your REST API. If you are looking for Swagger/OpenAPI 3.0, you can check out &lt;a href="https://github.com/tfranzel/drf-spectacular"&gt;drf-spectacular&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Django Debug Toolbar
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/jazzband/django-debug-toolbar"&gt;django-debug-toolbar&lt;/a&gt; package makes debugging a breeze. Django's default debug mode is definitely a very useful tool but django-debug-toolbar is a step above. You can see how much CPU time it takes to process the response, how many [and what] SQL queries are being executed, which static files the request is fetching, details about your template, list of all of your context variables and many more.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Django Shell and Management Commands
&lt;/h2&gt;

&lt;p&gt;Django shell is like a Python shell but with everything that Django is setup with on your project settings. You can call all of your apps, models and anything that's defined in your project really. Just type in &lt;code&gt;python manage.py shell&lt;/code&gt; in your virtual environment and you're inside the Django shell. This can come in handy for testing different ORM queries with your defined app models as well as trying out APIs of third party packages.&lt;/p&gt;

&lt;p&gt;You can use custom management commands with &lt;code&gt;manage.py&lt;/code&gt; for doing tasks. For example, you might need to insert data into your database from a csv file or a daily cron job for doing something that is related to the database. You can't access the database with the Django ORM from outside the application [for example, a cron job]. But if you define your task in a management command, you can call it from anywhere with the Python from that project virtual environment using &lt;code&gt;python manage.py your_command&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There are many useful management commands can already be found in different third party packages. One such package is &lt;a href="https://github.com/django-extensions/django-extensions"&gt;django-extensions&lt;/a&gt;. It comes with many helpful commands that can help you in many different scenario in development. You can drop the whole database, get a list of all of your urls and many more. One feature I particularly like is that I can generate a visual representation of my models using &lt;a href="https://github.com/django-extensions/django-extensions#:~:text=%24%20python%20manage.py%20graph_models%20-a%20-o%20myapp_models.png"&gt;this&lt;/a&gt; command. When the codebase grows big and I need to get an overview of how all of my models are connected, it comes in very handy.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Logging with Sentry
&lt;/h2&gt;

&lt;p&gt;Well, &lt;a href="https://media.giphy.com/media/uh2RP33ezYpnW/giphy.gif"&gt;the night is dark and full of (t)errors&lt;/a&gt;. And you can't just play &lt;a href="https://media.giphy.com/media/13f5iwTRuiEjjW/giphy.gif"&gt;Jon Snow&lt;/a&gt; when the users start complaining about getting server errors.&lt;/p&gt;

&lt;p&gt;In development, when your debug mode is on, you can just go through the very helpful debug messages that Django helps you with. But it's not the same in production. You should definitely &lt;a href="https://mattsegal.dev/django-gunicorn-nginx-logging.html"&gt;setup logs&lt;/a&gt; in your Django projects but additionally, a third party tool like &lt;a href="https://sentry.io/welcome/"&gt;Sentry&lt;/a&gt; can save you a ton of time and hassle. The setup process can't be simpler, you just sign up and &lt;a href="https://docs.sentry.io/platforms/python/guides/django/"&gt;add a few lines&lt;/a&gt; to the Django settings file and that's it!&lt;/p&gt;

&lt;p&gt;To get you started, the free tier gives you to save 5K errors, 10K transactions and 1GB attachments for 1 user with 30 day data retention. And you don't need to wait for your users to start complaining that your site isn't working, Sentry will send you emails when it catches new errors.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Environment Management - pip-tools and Docker
&lt;/h2&gt;

&lt;p&gt;You should always pin the exact version of Django and other pip packages that you are using in your Django project in a requirements.txt file. You can easily do it with &lt;code&gt;virtualenv&lt;/code&gt; and a &lt;code&gt;pip-freeze&lt;/code&gt; command. But the issue that comes up with this is that it exports all the package names that are in your virtual environment. There can be many dependencies of a specific package and if you want to upgrade one, you'll need to update all of it's dependencies manually as well along with it. Also, there are packages that you need only in development like &lt;code&gt;black&lt;/code&gt;, &lt;code&gt;pylint&lt;/code&gt; or &lt;code&gt;django-debug-toolbar&lt;/code&gt; that you definitely don't need in production. To deal with all these, there is an awesome package called &lt;a href="https://github.com/jazzband/pip-tools"&gt;pip-tools&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With the help of this package, you only need to pin your packages in a &lt;code&gt;requirements.in&lt;/code&gt; file and when you compile this file, it'll generate a nicely formatted &lt;code&gt;requirements.txt&lt;/code&gt; file that will have all the dependencies with notes for which one of them is coming from which specific package. You can also pin your development packages in &lt;code&gt;dev-requirements.in&lt;/code&gt; file and keep your development tools separate.&lt;/p&gt;

&lt;p&gt;Now you have taken care of the version of the pip packages, how about your Python version? Or exact PostgreSQL version that you are using in your development? Or even further, the version of your operating system that's all of these are running on?&lt;/p&gt;

&lt;p&gt;When you run your application, it's behavior depends on everything that it's using [and not using, that are running alongside it on the same operating system]. All of these can influence how it's running and performing. To isolate the application and to make sure it works the same no matter where it's running, you should use &lt;a href="https://www.docker.com/"&gt;Docker&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Getting started with Docker can easily feel overwhelming for a newcomer. &lt;a href="https://testdriven.io/blog/dockerizing-django-with-postgres-gunicorn-and-nginx/"&gt;Here&lt;/a&gt; is an awesome article how you can user Docker with your Django project. This is a three part series and it walks you through how you can use Docker in your development as well as deploying it live.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Using UserAdmin in the Django Admin for Custom User Model
&lt;/h2&gt;

&lt;p&gt;One of the most handy "batteries" included with Django has to be the Django Admin. It can be very useful for inspecting the data in the database with a model-centric interface as well as for inputting / inspecting / managing test data while in development. When we add a model to the Django Admin, the usual approach is to use &lt;code&gt;ModelAdmin&lt;/code&gt; from &lt;code&gt;django.contrib.admin&lt;/code&gt; but if you use it with a custom user model, there is an issue. And if you are not already aware, defining the custom user model should be something that you should do as one of the first things when you start a new Django project as &lt;a href="https://docs.djangoproject.com/en/3.2/topics/auth/customizing/#:~:text=Using%20a%20custom,sufficient%20for%20you."&gt;suggested&lt;/a&gt; by the Django documentation itself.&lt;/p&gt;

&lt;p&gt;Just like most other web frameworks, Django doesn't store the passwords as plain texts. It uses a hash function to encrypt it and then stores it in the database. So even if the data is compromised, it won't be possible to decipher what actually the password is for a specific user.&lt;/p&gt;

&lt;p&gt;Going back to the issue about using &lt;code&gt;ModelAdmin&lt;/code&gt; with a custom user model is that your user create form and user edit form will present you with password input fields where you'll need to enter the password in the hashed format itself. If you enter &lt;em&gt;yourawesomepassword123&lt;/em&gt; as your password and save the user, that user won't be able to log in with &lt;em&gt;yourawesomepassword123&lt;/em&gt; because that's not the actual stored password. The actual password would be the value that's is &lt;em&gt;yourawesomepassword123&lt;/em&gt; after hashing.&lt;/p&gt;

&lt;p&gt;The solution is to write user creating and updating forms based on &lt;code&gt;UserCreationForm&lt;/code&gt; and &lt;code&gt;UserChangeForm&lt;/code&gt; from &lt;code&gt;django.contrib.auth.forms&lt;/code&gt; and use them in the admin that will be based on &lt;code&gt;UserAdmin&lt;/code&gt; from &lt;code&gt;django.contrib.auth.admin&lt;/code&gt;. You can find all about how to do it on &lt;a href="https://learndjango.com/tutorials/django-custom-user-model"&gt;this awesome tutorial&lt;/a&gt;. This way you will have the freedom of creating new users from the Django admin with ease.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. TDD - Test Driven Development
&lt;/h2&gt;

&lt;p&gt;Test driven development is where you write your tests even before you code a feature. The idea is that you will think of the test case, write a test and write the function that will make the test pass. It is certainly not easy to always follow this and getting started with it can feel overwhelming. But for the long run, it'll help you save so much hours of pain and misery for fixing unwanted bugs that happen in production.&lt;/p&gt;

&lt;p&gt;I would suggest checking out &lt;a href="https://testdriven.io/"&gt;testdriven.io&lt;/a&gt; for getting up and running with TDD [and Docker]. I can vouch that their paid courses are worth every penny without having any affiliation with them.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Starter Templates and Style Guides
&lt;/h2&gt;

&lt;p&gt;There are a number of things that always need to be done when starting a new project which are always the same. There are a some fantastic starter templates that can help jumpstart your Django projects. I'm listing a few of them below - &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/pydanny/cookiecutter-django"&gt;cookiecutter-django&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/wsvincent/djangox/"&gt;djangox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/wsvincent/drfx/"&gt;drfx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jpadilla/django-project-template"&gt;django-project-template&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/erroneousboat/docker-django/"&gt;docker-django&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When the project keeps getting larger and multiple developers working on the same project [even while working alone], it is possible to end up with different style codes in the same codebase. It's better to follow a specific style guide throughout all of the codebase so it's easier to read, modify and maintain in the long run. It's also easier to get new developers onboard with the project with a specific style guide. A few of the popular styles guides - &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://django-best-practices.readthedocs.io/en/latest/"&gt;Django Best Practices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/HackSoftware/Django-Styleguide"&gt;Django Styleguide by HackSoftware&lt;/a&gt; which also comes with &lt;a href="https://github.com/HackSoftware/Styleguide-Example"&gt;an example project&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/phalt/django-api-domains"&gt;django-api-domains&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.feldroy.com/products/two-scoops-of-django-3-x"&gt;Two Scoops of Django 3.x: Best Practices for the Django Framework&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>django</category>
      <category>webdev</category>
      <category>python</category>
    </item>
  </channel>
</rss>
