OverIQ.com

Creating Django Project

Last updated on July 27, 2020


Creating a Project #

To create a new Django project make sure that the virtual environment is active and your current working directory is set to djangobin, then issue the following command:

$ django-admin startproject django_project

This command will create a new directory named django_project inside djangobin directory. The django_project directory is also known as Django project root directory or simply project root directory. Its directory structure should look like this:

1
2
3
4
5
6
7
8
9
django_project/
├── django_project
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

1 directory, 5 files

At the top level, our newly created django_project directory contains the following two items.

  • A directory of the same name as your project root directory i.e django_project.
  • A Python script called manage.py.

The directory django_project/django_project is known as Project configuration directory. Inside it you will find the following four python files:

Filename Description
__init__.py A special empty file that tells Python that the current directory should be treated as a Python package.
settings.py This file contains all the settings and configuration of the Django project.
urls.py A Python script to store the URL patterns of the Django project.
wsgi.py A Python script to run development server and also deploy the project to the production environment.

manage.py - A command-line utility to interact with or maintain your Django project. We can view the various arguments (or subcommands) provided by this file by simply executing it.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
$ ./django_project/manage.py 

Type 'manage.py help <subcommand>' for help on a specific subcommand.

Available subcommands:

[auth]
    changepassword
    createsuperuser

[contenttypes]
    remove_stale_contenttypes

[django]
    check
    compilemessages
    createcachetable
    ...    
    startapp
    startproject
    test
    testserver

[sessions]
    clearsessions

[staticfiles]
    collectstatic
    findstatic
    runserver

If you are on Windows, always precede the Python file with the python command:

C:\Users\overiq\djangobin> python django_project/manage.py

One of the most basic subcommand is runserver (last in the list), which is used to run the Django development web server. Let's see how it's done.

First change your current working directory to the directory where manage.py is located using the cd command and then execute runserver subcommand as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$ cd django_project
$ ./manage.py runserver
Performing system checks...

System check identified no issues (0 silenced).

You have 13 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.

March 19, 2018 - 08:23:19
Django version 1.11, using settings 'django_project.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

There are few points to notice here. The first line:

System check identified no issues (0 silenced).

Indicates that no errors were found in your Django project. If there had been errors then ./manage.py runserver would have failed to start the server. The second point to note here is the following:

1
2
You have 13 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.

This line tells us there are some unapplied migrations in the project. In Django, we use migrations to alter the state of the database. Don't worry too much about what migrations are, we will discuss them in depth in later chapters.

The third and the most important point, for now, is the address of the Django development server i.e http://127.0.0.1:8000/. Open your favorite browser and visit http://127.0.0.1:8000/. You should see a page like this:

To stop the development server hit CTRL+C.

By default manage.py always starts the development server at port 8000 but you can change it to some other port using the following command.

$ ./manage.py runserver <port>

For example, ./manage.py runserver 3000 will start the Django development at port 3000. In case you want to open port at a specific IP address, you can easily do that using the following command:

./manage.py runserver <ip-address>:<port>

For example, to run Django development server at localhost on port 4444, issue the following command.

$ ./manage.py runserver 127.0.0.1:4444

After every modification to the Python code, Django development server restarts automatically. So you don't need to manually restart the server every time for the changes to take effect. However, there are some actions like adding files don't trigger a restart. In such cases, you will have to restart the server manually.

Setting up the Database #

Django can be used with almost all popular databases like MySQL, Oracle, PostgreSQL (which is the preferred choice among Django developers), SQLite etc. As this is a beginner tutorial, we will use SQLite database. But why SQLite? Because there are no additional steps involved to install and configure SQLite database. SQLite already comes bundled with Python, so you don't have to configure anything to use it.

Django will automatically create an SQLite database named db.sqlite3 in the project root directory ( i.e djangobin/django_project ), the first time you execute the runserver command. We have already executed the runserver command once, so at this point, you should have SQLite database file named db.sqlite3 in your project root directory (djangobin/django_project).

1
2
3
4
5
6
7
8
django_project/
├── db.sqlite3   <-- SQLite database
├── django_project
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

If we were not using SQLite database then we can easily specify database configurations in the settings.py file located in project configuration directory (djangobin/django_project/django_project). As already said, the settings.py file contains all the settings related to our Django project.

Open settings.py file and scroll past halfway through it until you find
DATABASES setting. The DATABASES variable contains all the database specific settings. The default value of DATABASES variable should look like this:

djangobin/django_project/django_project/settings.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#...

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

#...

The ENGINE specifies the type of database backend Django is using. In our case we are using SQLite that's why it is set to django.db.backends.sqlite3. Here are some other backends to choose from:

Database ENGINE
MySQL django.db.backends.mysql
Oracle django.db.backends.oracle
PostgreSQL django.db.backends.postgresql

The NAME specifies the name of the database we are using. As SQLite database consists of a single file, it currently points to the absolute path of the db.sqlite3 file. That's all we need to use an SQLite database.

To use databases like MySQL or PostgreSQL, we would need to add some additional parameters like USER, PASSWORD, HOST and PORT. For example, here is how you would configure Django to use MySQL database.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'database_name',
        'USER': 'username',
        'PASSWORD': 'password',
        'HOST': '127.0.0.1',
        'PORT': '5432',
    }
}

Django Application #

In Django, project and application means different things. According to Django nomenclature - a Django project is a collection of configurations and applications, these configurations and application together make up the whole web application. In other words, a project is a complete web application and an app is just one feature. For example, an app may be a blog, a comment system, a forum, a chatbox or even a contact form. All of these small apps and configurations together constitute a Django project.

Django Built-in Applications #

Django already comes bundled with several built-in apps. To view these built-in apps, take a look at the INSTALLED_APPS setting at the top of the settings.py file.

djangobin/django_project/django_project/settings.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#...

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

#...

As you can see there are 6 apps installed by default, all of which ships with Django. Here is a rundown of each application.

  • django.contrib.admin – An admin site.
  • django.contrib.auth – A framework for user management and authentication.
  • django.contrib.contenttypes – A framework for content types.
  • django.contrib.sessions – A session framework.
  • django.contrib.messages – A messaging framework.
  • django.contrib.staticfiles – A framework for managing static files.

Some of these apps require database table while others don't. Recall that when we tried to run Django development server we got the following warning.

1
2
You have 13 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them

This warning tells us about "unapplied migrations". Unapplied migration means that there are some changes need to be committed before all the applications can run successfully. A migration is just regular Python file which describes the changes we want to commit to the Database. These changes can be as trivial as renaming a column and as complex as creating or altering database schema. At any point, we can use showmigrations subcommand of manage.py to get the list of applied and unapplied migrations.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
$ ./manage.py showmigrations
admin
 [ ] 0001_initial
 [ ] 0002_logentry_remove_auto_add
auth
 [ ] 0001_initial
 [ ] 0002_alter_permission_name_max_length
 [ ] 0003_alter_user_email_max_length
 [ ] 0004_alter_user_username_opts
 [ ] 0005_alter_user_last_login_null
 [ ] 0006_require_contenttypes_0002
 [ ] 0007_alter_validators_add_error_messages
 [ ] 0008_alter_user_username_max_length
contenttypes
 [ ] 0001_initial
 [ ] 0002_remove_content_type_name
sessions
 [ ] 0001_initial

The preceding output shows a list of unapplied migration files (without .py extension) under all the installed apps. We know that these migrations are unapplied because square brackets ([]) in front of the migration name is not checked. If they were applied we would see [x] in front of the migration name. From the output we can also infer that django.contrib.admin has 2 unapplied migrations, django.contrib.auth has 8, django.contrib.contenttypes has 2 and django.contrib.sessions has 1 unapplied migrations. To apply these migrations we use migrate subcommand.

In the terminal or command prompt enter the following command to apply the migrations.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
$ ./manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying contenttypes.0002_remove_content_type_name... 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 sessions.0001_initial... OK

Run the ./manage.py showmigrations command again. This time you will see [x] in front of each migration file because we have just applied the pending migrations.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
$ ./manage.py showmigrations
admin
 [X] 0001_initial
 [X] 0002_logentry_remove_auto_add
auth
 [X] 0001_initial
 [X] 0002_alter_permission_name_max_length
 [X] 0003_alter_user_email_max_length
 [X] 0004_alter_user_username_opts
 [X] 0005_alter_user_last_login_null
 [X] 0006_require_contenttypes_0002
 [X] 0007_alter_validators_add_error_messages
 [X] 0008_alter_user_username_max_length
contenttypes
 [X] 0001_initial
 [X] 0002_remove_content_type_name
sessions
 [X] 0001_initial
$

At this point, we are not expecting you to understand migrations completely. We will learn about them in detail in lesson Migrations in Django. For now, just remember this - In Django, we use migrations to create/alter/delete tables in the database. We will examine the tables created by the migrate subcommand in the next section.

Run the development server again using the runserver subcommand. This time you will not see any warnings about unapplied migrations.

1
2
3
4
5
6
7
8
9
$ ./manage.py runserver
Performing system checks...

System check identified no issues (0 silenced).
March 19, 2018 - 10:01:48
Django version 1.11, using settings 'django_project.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
[19/Mar/2018 10:01:56] "GET / HTTP/1.1" 200 1716

It is not necessary to use all apps provided by Django. If you don't want to use any particular app just remove it from the list. Let's say for some reason you don't want to use django.contrib.staticfiles app, after removing django.contrib.staticfiles, the INSTALLED_APPS list would look like this:

djangobin/django_project/django_project/settings.py

1
2
3
4
5
6
7
8
9
#...
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',    
]
#...

But for now we need everything, so add django.contrib.staticfiles back to the INSTALLED_APPS list. Finally, INSTALLED_APPS setting should look like this:

djangobin/django_project/django_project/settings.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#...
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',    
    'django.contrib.staticfiles',
]
#...

Viewing the Database #

In this tutorial, we will use a Graphical Database Management program named Navicat to view the current state of our SQLite database from time to time. Programs like Navicat makes it really easy to view tables, create/alter records graphically without writing a single line of SQL.

However, if you are an SQL pro and know SQL commands by heart, you are free to open db.sqlite3 file from the command prompt or terminal and proceed from there.

Navicat is not a freeware but, they do offer 30 day trial period. There are many other freewares Sqlite Browser, HeidiSQL, Sqlectron, Valentina Studio, DBeaver etc which allows you to do more or less same things.

The following are instructions to open an SQLite database using Navicat, instructions for other programs are more or less same.

Start Navicat Premium and go to Connection > SQLite.

In the New Connection window, specify the connection name, select "Existing Database File" and browse the location where db.sqlite3 file is located. Skip the password field and click the "Test Connection" button at the bottom of the window. If the connection succeeds, close the dialog box and save the connection by clicking the OK button. In case you encountered any error check the location of the SQLite database file and try again.

To view the tables click on the connection name on the left pane, then double click on the "main". You should see a list of tables in the right side of the window, as follows:

As you can see, currently there are 11 tables in the SQLite database.

Creating Django application #

To create a new app, first, make sure your current working directory is same as where the manage.py file is located. After that execute the following command.

$ ./manage.py startapp djangobin

This command will create a new directory named djangobin inside the project root directory ( djangobin/django_project ). The directory structure of our newly created directory is as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
djangobin/
├── admin.py
├── apps.py
├── __init__.py
├── migrations
│   └── __init__.py
├── models.py
├── tests.py
└── views.py

1 directory, 7 files

Here is a rundown of each file and folder:

Filename Description
admin.py This file contains all the configurations necessary to connect our djangobin app to the admin app supplied by Django. We will learn in detail how to do so in lesson Django Admin App.
apps.py This file contains application specific configurations.
__init__.py The __init__.py file is just the Python way of saying treat this ( djangobin ) directory as a package.
migrations This directory will store all our migration files. In other words, it will store all the changes made by us in the database.
migrations/__init__.py The __init__.py file is just the Python way of saying, treat this ( migrations ) directory as a package.
models.py This file contains our application models. In other words, this is the place where we will define tables and relationships between them.
test.py This file contains functions to unit test our app.
views.py This file contains view functions which handle requests and return responses.

We have created a new app djangobin, now we must inform our Django project about its existence. To do so, open settings.py file located in project configuration directory (djangobin/django_project/django_project) and append 'djangobin', at the end of the INSTALLED_APPS list as follows:

djangobin/django_project/django_project/settings.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#...

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'djangobin',
]

#...

To verify whether Django picked up our new djangobin application restart the server. If you can successfully start the server without any errors, then it means you are ready for the next step.