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
Directory | Description |
---|---|
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.py | If 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.