How to Structure a django project for Beginners

Photo by Kaleidico on Unsplash

How to Structure a django project for Beginners

When I started learning Django, I was very confused about how do I make the first project in Django, how do I start Django from scratch, and How to I organize files in Django for multiple apps or templates. You can work with Django's default configurations but at some point, you will want to follow Django's best practices and save your time by creating some kind of generic solution. So why not use this, I wrote this guide to help you get started every time you start a new Django project.

To set up a Django project you can clone this django-structure repository.

It is a very beginner-friendly repository that can be used by any beginner Django developer. It has the latest and stable Django version installed, environment variables config support, and a few custom Django features that every beginner developer should use in every Django project.

Setting up the django-structure repository in local

Open your terminal and clone the django-structure-for-beginners repository using the command below.

git clone https://github.com/raturitechmedia/django-structure.git
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

Install these system-level dependencies

sudo apt-get update
sudo apt-get install virtualenv
sudo apt-get install memcached

Now, change your directory to django-structure

cd django-structure

Let's remove .git directory so that you can set your own repository later

rm -rf .git

Now create a virtual environment using python 3, I am using virtualenv command to create virtual environment. You can follow this guide if you want to know more about creating a virtual environment with python

virtualenv -p python3 venv

Now activate your virtual environment

source venv/bin/activate

After activating the virtual environment, you have to install the requirement from the requirements.txt file, run

pip install -r requirements.txt

Now create an environment file .env and paste all the values from this sample env file inside .env file.

touch .env

Once this that you have to change inside your .env file is the value of SECRET_KEY. You should never upload this value to your repository because of security reasons. Now generate a secret key the same way Django generates a secret key, type python manage.py shell and paste the below code

from django.utils.crypto import get_random_string

chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)'
get_random_string(50, chars)
'u@!4qul8q*kiz#m8k$o7tmr*7o+wz#7%vldi_&#upg=#*5n9(-'

Now copy the generated string and replace it with the SECRET_KEY inside the .env file.

Now let's create a few of the required folders

mkdir -p static/{css,js,img} static_cdn/{static_root,media_root} templates/{snippets,layouts} apps logs locale

Ok. Let's run migrations

python manage.py makemigrations
python manage.py migrate
Applying contenttypes.0001_initial... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0001_initial... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying users.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying sessions.0001_initial... OK

That's it! Now you can run the project and start building cool stuff.

python manage.py runserver
Performing system checks...

System check identified no issues (0 silenced).
May 02, 2022 - 11:42:09
Django version 3.2.13, using settings 'conf.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Open http://127.0.0.1:8000 and you should see this.

If you are facing any issues not able to run the project. You can join this discord community and post your query on the Django channel. I will be happy to help.

If you have followed this guide previously then I believe you have an understanding of what all features are available and the changes we did so far. But if you are following this django-structure guide the first time and want to dive deeper to get an understanding then you should read further.

Understanding django-structure for beginners in detail

Dependencies Explanation

Python3 is required and Django's latest long-term support (LTS) version 3.2.x is used. I would suggest you not upgrade until the new LTS Django version is released. When it releases I will update the repository myself. Read this guide if you want to install python3 in your system.

Environment Variables

Environment variables are an important part of every project because they are various things like SECRET_KEY that we don't want to have other control over or manage a single app in multiple environments we can set DEBUG=TRUE locally and DEBUG=FALSE in production.

So if you want to add an environment variable, just add it in .env file and in case there are variables in .env-sample file and you don't need them for your project then it's a good practice to declare those variables with any dummy value.

Like even if you don't need these email variables in your .env file, you can set these to any dummy. Maybe later you might need these at some point then you can just set these with the right one.

EMAIL_USE_TLS=True
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_HOST_USER=develop@raturi.in
EMAIL_HOST_PASSWORD=develop@123
DEFAULT_FROM_EMAIL=Develop<develop@raturi.in>

To access any environment variable, you can declare these inside the django-structure/conf/settings/base/env.py file.

NEW_VARIABLE=config('NEW_VARIABLE')

Access these variables anywhere in your code like

from django.conf import settings

settings.NEW_VARIABLE

Read this guide if you want to read more about managing environment variables in django.

Django's User model

Django’s built-in User model is great but as our application grows we want to store a few more data related to our user. One of the ways is to extend the user model ideally at the beginning of the project since it will dramatically impact the database schema and if you do it later you will have a hard time doing it as it has various references with other tables.

Everything is implemented here if you want to add some new fields to your user model, you can add a field in this django-structure/apps/users/models.py file like below.

from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
from django.db import models
from django.utils import timezone
from apps.users.managers import UserManager

class User(AbstractBaseUser, PermissionsMixin):
 email = models.EmailField(unique=True, null=True, db_index=True)
 is_active = models.BooleanField(default=True)
 is_staff = models.BooleanField(default=False)
 date_joined = models.DateTimeField(default=timezone.now)

 REQUIRED_FIELDS = []
 USERNAME_FIELD = 'email'
# =============== Introducing New field here ==============
NEW_FIELD = models.CharField(max_length=255)

 objects = UserManager()

and now run your migrations to apply these changes.

python manage.py makemigrations
python manage.py migrate

Project Layout

Your project layout should look something like this. I have only included the top-level directory in the snippet below, so don't panic if yours doesn't match.

├── apps
│   ├── pages
│   └── users
├── conf
│   ├── hosts.py
│   ├── settings
│   │   ├── base
├── db.sqlite3
├── logs
│   └── django.log
├── manage.py
├── README.md
├── requirements.txt
├── static
├── static_cdn
│   ├── media_root
│   └── static_root
└── templates
├── base.html
└── pages
└── home.html
DirectoryDescription
apps/All the apps created by python manage.py startapp command should be placed inside this.
conf/settings/base/All the settings should be placed here. You can follow this documentation on split-settings django
conf/hosts.pyIf you own different domains and want to manage those in this Django app, then you can follow django-hosts documentation
logs/Logs from different apps should be placed here.
static/Place your static files like CSS, images, and js inside this directory.
static_cdn/media_root/Any uploads done by the user via UI should be placed here.
static_cdn/static_root/All the static files after running the command python manage.py collectstatic will be stored inside this directory.
templates/All the templates should be placed inside this directory. For example, templates related to app pages are placed inside templates/pages.

Compress static files in production

Here you also get support for compressing and minifying static files in production. It is totally optional and in case you made up your mind to optimize your static files for increasing the website speed, you can follow this compressing and minifying static files in django guide.

That's it.

Did you find this article valuable?

Support Nitin Raturi by becoming a sponsor. Any amount is appreciated!