15 minutes read

Django uses a convention that contains several requirements for storing elements. Following that convention makes it easier to work with the legacy code, as everybody knows where to look for the code responsible for particular functions.

Django comes with the django-admin utility that creates a project's skeleton. Note that Django uses the following naming convention:

  • project — a collection of settings for Django instance, applicable to the whole website;

  • application — a submodule of a project that implements certain functionalities

To isolate units of code with different business logic, you can create multiple applications within one project. For example, an online store project can have a blog, authors, forum, and support applications. Applications can be used many times so you can copy them to other projects. For example, functionalities like user registration, login, logout, password resets or profile editing can be bundled into a user application and used over and over again with any website that needs to identify its users.

Dividing the code into applications helps control the complexity as the code base becomes larger with time.

Starting a new project

The django-admin utility creates a basic structure of the files for both project and application, with the use startproject and startapp commands, respectively. Note that different versions of Django have different default layouts, and whichever version you use, try to stick to the structure it provides; it will make your code easier to maintain.

Let's continue the example with the online store. To create the project and the first application, run the following code in the command line:

django-admin startproject store
cd store
django-admin startapp blog

The first command creates a new folder with the project skeleton (your website is called store in this example). Note that files are created in another subfolder with the same name, except for the manage.py file.

The second command moves you into that folder, and the third one creates a new Django application in a subfolder (blog).

Having executed these commands, Django will automatically create a whole file tree for the project. The store folder will be the root of your site (project) and the subfolder blog will be the first application you've created.

structure of a Django project

In the next sections, we'll take a look at the most important files in this structure: manage.py, settings.py, models.py, and templates with views.

Manage.py

This file is a command-line utility for administrative purposes. One can interchangeably use django-admin <commmand> or python manage.py <command>.

Some of the most common commands executed with manage.py include:

  • runserver starts a local web server. The development server automatically reloads Python code for each request, as needed. You don’t need to restart the server for code changes to take effect;

  • makemigrations detects changes in models and creates scripts to apply these changes to database. Migrations files are stored in an app/migrations folder.

  • migrate synchronizes the database state with the current set of models and migrations;

  • dumpdata and loaddata outputs and loads data from a database; these commands are used to migrate data (opposed to migrate, which handles only data structure of the database)

For more commands, please refer to official documentation.

Settings.py

This file contains various project-level parameters such as language and time-zone setup or definition of database (sqlite3 by default). This is where you can turn on/off debug mode of your server or define hosts allowed to connect to the application.

In the beginning, default values will be enough, though you will need to add your application name to the INSTALLED_APPSvariable:

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

More information about configuration stored in the file can be found in the official documentation.

Models.py

The components can be linked with the following files and folders:

store/
├── blog
    ├── ...
    ├── models.py    # Model
    └── views.py     # Views
├── store
    ├── ...
    └── urls.py      # Views

Now, let's take a look at each of the components in more detail:

store/
└── blog
    └── models.py

As you remember, the Model component is in charge of the data in your project. It includes all the database operations with the project's business objects. A business object is simply an entity with custom attributes; it reflects a structured piece of data from your application that you want to store persistently or temporarily. For example, in a shop application, it can be a customer, a product, and a purchase; in a blog, business objects can be authors, posts, and comments.

To keep your code clear, implement all operations with the business objects in the models.py module. The bigger your codebase gets, the harder it is to maintain everything in one file, but it's a good starting point.

This is how models.py may look like in a very simple project:

from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()

Django has the built-in Model class for creating database models. In the snippet above, we create our model for posts that has two fields: a title and a content.

Django provides some of the most used models right out of the box. When you start with your own projects, you may use the User and Group models from django.contrib.auth.models. The User is a registered person in your web service and the Group is a collection of users. We'll create some of those and discuss how to work with them in detail later when we attach a database to the project.

Templates

store/
├── blog
    └── templates
        └── blog
            └── index.html
└── templates
    └── base.html

No one will know what the service does, unless it has some form of visual rendition. Templates are a representation of your web service; it is what the user sees.

This component is stored in templates, files that support Django/Jinja2 template languages. They can also include content with HTML, CSS, and JavaScript. The template language utilizes the ability to use similar constructs you use in Python: it has a different syntax but the same function words. Here's how the simplest template file may look like:

<!DOCTYPE html>
<title>Example</title>

<h1>First template</h1>

<p>This is a simple html-page without any additional functionality.</p>

Yes, it's just a plain HTML file.

The templates directory can be created for the whole project or for each application separately. For now, let's begin with high-level templates placing.

Views.py and urls.py

store/
├── blog
     └── views.py
└── store
      └── urls.py

Templates and models are good tools, but something should manage how they work together, and here we turn to views. There are two types of files: views.py and urls.py.

In urls.py, you define the routing for your service. Routing is a process of matching request links with appropriate view handlers. A view handler is a function or a class that responds to requests.

Main routing links should be registered manually in <project_name>/<project_name>/urls.py. First, let the project know what address our application belongs to. Paste the following code to the project's urls.py file:

from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('', include('blog.urls')),   # defining our app routings
    path('admin/', admin.site.urls),         # defining admin panel
]

The admin panel is part of Django framework, as you can see in the import statement in the first line.

Django admin panel provides a web user interface to the database not only for the admin user, but also other users with appropriate privileges. More information about The Django admin site can be found in official documentation.

Now let's make it clear to the application what links need to be processed inside of it and where they lie, relative to the main links. Create a new urls.py file in your application folder, it needs to be at <project_name>/<app_name>/urls.py and paste the following code:

from django.urls import path
from . import views      # importing all handlers from views.py

urlpatterns = [
    path('', views.example_view, name='NAME_OF_YOUR_VIEW'),
]

The urls.py file in an application defines routes specific to that application. This allows developers to create reusable applications that can be easily integrated into other projects.

View handlers are defined in the corresponding views.py file. View functions play a mediator role between the model and the templates layers. Let's create the example_view from the example above:

from django.http import HttpResponse


def example_view(request):
    return HttpResponse("Hello, world")

The HttpResponse object is a special object that stores all the data required to be returned to the client. You'll discover more about it in the next topics, for now it's enough to say that the example view returns the Hello world line.

Conclusion

You've learned to create a new project with the help of django-admin and repeated the basics of the MTV pattern. You've also got to know what files in a project are associated with which component and even peeked at their content. We hope it helps you understand better the structure of Django projects!

13 learners liked this piece of theory. 0 didn't like it. What about you?
Report a typo