Here on Habré there are many different instructions for using Django. These instructions often include a lot of code and represent the sequence of steps that you need to take to create a project.

When I started to learn Django and Wagtail with such instructions, I was often confused that a couple of commands create a bunch of obscure files (especially at the start). The subsequent description of these files in the instructions contained too many details that were difficult to learn at a time.

In this post, I would like to look at Django from a very "philosophical look" - a minimum of code, a maximum of general facts. I think that such a look will help those who want to start learning Django but get lost at the start.

I also want to say that I am not a professional in web programming - I’m rather an amateur in this area who is interested only in personal projects - one of them is a site for decoding DNA test data - written in Wagtail.

First, let's remember that a website on the Internet is just a program that probably works on almost the same computer that is in front of you.

Your computer (phone, etc.) sends some kind of request to someone else's computer on the Internet, it processes it and answers it. When processing someone else's computer, it may make a request or write to the database. Now imagine that you need to program a computer on the Internet so that it processes each request correctly.

This can be done in general in any programming language - you receive a request and perform something on its basis. But imagine how many options there can be how to program this computer - there can be infinitely many of them! For example, you could write a function something like:

Если запрос == ответ "Привет" Если запрос == ответ "Hallo"... 

I think it’s clear that this would be a terrible programming option.

We need to make everything so that the code is readable, safe, easily complemented, uses some features of the language in which it is written...

With this set of tasks, you need to come up with some kind of concept.

Django Concept

Django suggests splitting everything into " layers ". Layers are responsible for the different components of your program. There is a connection between layers, but it does not complicate the development of each layer in isolation (without much attention to the other layers) - in Django this is called loose coupling.

Here are a few important layers of Django:

  • Models (Models) is the layer of your data and how you store it in the database
  • Views (views) this layer collects all the data that is needed to create web pages or process data submitted via forms
  • Templates (Templates) this layer receives data from views and displays it on a web page (in this layer you are already working with html)
  • Links (url) this layer organizes the operation of links on your site which link you need to create what kind and what template
  • Forms (Forms) this layer helps to create and process web forms for user data
  • .

Django provides tools for creating such layers and the functioning of the program is to exchange data between layers.

Here I will dwell in more detail on the Models, Views and Templates layers.

Model layer

The first and probably the most important layer is models (models) - it is responsible for the database. A database is all sorts of tables - for example, there may be a table “users” of this kind:

As you can see, in the database, each line is a record related to the user of the site. The line contains data of various types - in our case, numbers and text.

SQL is a common database language - with specific commands you can create new tables in the database or add and receive data to and from existing tables.
SQL has vulnerabilities - more .In short - if you put quotes and semicolons in a certain way in the data that is sent to the SQL command, some of this data can be interpreted as part of the SQL command.

Django takes all the headaches associated with SQL problems - you don’t even need to know SQL to use Django, you only need python - Django will generate SQL commands for creating tables, searching and writing data to tables, and all this will be safe.
Django's idea is that python classes repeat the structure of your database tables.

That is, for the table above, I can create a class in python something like:

class User: def __init__(id, name, surname, karma) ... 

but how to associate such a class with a database? This is where Django's magic begins:
# мы просто импортируем модуль models из Django from django.db import models # создаем класс, который наследует models.Model class CustomUser(models.Model): # создаем поля для базы данных в классе name=models.CharField(max_length=20) ... karma=models.FloatField(...) ... # Еще одна таблица в базе данных - статья class Article(models.Model): # создаем название и содержание статьи title=models.CharField(...) content=models.TextField(...) ... 

You simply use django.db.models.Model to create a class, then each field in your class is also a field taken from django.db.models. In my case, the name field is a CharField text field, the karma field is a float number. A list of all fields (Field types) is in the official documentation .

Each field has options (Field options) - in the code above the option is max_length=20 . Options depend on the fields that you create in the database - for example, max_length=20 is the maximum length in characters of the name field in the database. The documentation for the link above also describes options for all fields.

Based on this code, Django will create a table in the database itself, and what I called fields in the class will be columns in this table. Django also gives you convenient python commands on how to get or write values ​​to a database. Everything is done using the models.Model methods as well as the “Manager” abstraction, which Django is responsible for communicating with the database (in this post I will not discuss these abstractions in detail). For example, CustomUser.objects.filter (name="Michael") will return all users with the name "Michael".

Such a relationship between rows in a database and objects (instances, instances) in Python is called Object-relational mapping - in our case, Django-ORM.

And our models repeat the structure of the database and at the same time are classes in Python. This means that you can add methods to models (classes in Python). For example, continuing the logic of the Habr site, I can add a method to change karma:

from django.db import models class CustomUser(models.Model): ... # пример метода в модели Django def change_karma(self, other): .... if...: self.karma=self.karma +1 ... else: ... 

Here other is another user. As you know, there is a certain logic to adding karma. For example, I can create all this logic in the specified method.

In Django, you think which tables you want to create in your database and then just create the python classes as in the example above.

Layer views

The next important layer, in my opinion, is the views (views) layer. Your models are some abstractions that are convenient for you to work with or intuitively understandable. But, when you want to show something to users, then, perhaps, you will be interested in other abstractions.

For example, you created three models in Django: CustomUser, Article and Advertisement with different fields. Article model is an article of a site, Advertisement is an advertisement that you display on a site, CustomUser is a registered user of the site.

When you want to create a web page with an article, you will need data from several of your models at once - of course you want to show all the fields in the article itself (title, content, etc.), you most likely also want to show some kind of advertising next to this article. Moreover, advertising does not depend on the content of the article but on the behavior of the CustomUser user. With this approach, some kind of logic will be needed - how to collect data. So, the view layer in this case will be a suitable place for this logic. Here you can collect all the data that will relate to what you want to show.

There are two types of view types in Django - functional and class.

The functional view is just a Python function with the request argument - this is a request to your site. It contains information about the user, the type of request, and much more. Based on this information, you form an answer and return it in your function.

Another type of view is class. It allows you to create views not based on functions, but views as instances of classes. Here Django also provides a bunch of life-saving classes and functions.Suppose you want to create a view based on an Article article:

# импорт полезного класса from django.views.generic import DetailView # импорт созданной в другом файле модели Article from.models import Article # создание классового вида class ArticleDetailView(DetailView): # модель на основе которой мы хотим создать вид model=Article # имя, которое будет использовано в html шаблоне (это другой слой - рассмотрим далее) context_object_name='article' # имя html шаблона, на основе которого будет создана веб страница template_name='article/article_detail.html' 

The DetailView-based class view will automatically collect all the information in the Article model and then send it to the next Django layer:

Layer Templates

In the code above, template_name is a variable for the name of the html template that will be used to form the web page that will be shown to the user. Here is an example of code from such a template:

<h1>{{ article.title }}</h1> <div>{{ article.content }}</div> 

{{article.title}} and {{article.content}} are the name of the article and its contents, enclosed in html tags. title and content repeat the field name for the Article model that you created in the Model layer. The word article we specified in the context_object_name in the form. As a result of processing, Django will insert the appropriate fields from Article into the template.


This is a general look at some Django layers. The described concept allows you to separate the individual blocks of the program. In the model layer, you create convenient abstractions of your database, in the views layer you decide what data you want to show, and in the templates layer you create your html-based page design and add a little logic to the templates using the Jinja - this is from the example with curly braces - {{}} .

I have not touched on quite a few important topics - for example, the relationship between your models. Each article can have one author or several authors - Django can easily cope with any of these options, and with a single line in Python you can get the author of the article or a collection of authors as instances of the Author class, created on the basis of models.Model.

But where are so many files from?

If you are creating some kind of complex application with a bunch of Models, views, etc. then this huge amount of code needs to be split into separate files somehow. And it is desirable to organize the files into folders so that the file with the article’s models is in the same folder as the article’s types.
Here comes another key Django idea - applications that deserve a separate post.