Evgenij LegotskojSept. 18, 2016, 3:41 a.m.

Django - Tutorial 003. Model, Template, View on Django

In Django uses a modular system of applications, where one application is composed of several applications, each responsible for its functionality. As you have noticed, at the time of this writing, the site has a section "Knowledge", in which there are several sections, which have divided the article.

When working with the previous site on Wordpress, mindlessly spend time on the addition of new articles to the list of lessons on Qt. On this same site the page is automatically generated and save a new article is published with the status, this article will automatically enters the relevant section of the list.

I suggest to understand how it is implemented in a minimal version of the example EVILEG COM.

Project structure

Specifically, this website uses two applications in the project:

  1. home - an application that is responsible for the main index page, error pages and basic templates
  2. knowledge - application which meets just for the articles and sections of articles

If you look in detail, the structure of the project will be as follows:


A few words about the project creation and application in the project. We used PyCharm development environment, which prepares the project with included core modules, including the admin, so I will talk about that was not included by default.

You should use the following command to create the application:

python manage.py startapp home
python manage.py startapp knowledge

Configuration the settings.py

In order to have available application modules, you should connect them in the configuration file of the project.



The project uses two kinds of models:

  1. Section - Sections, which bring together all the articles one by one common feature, membership in a particular category
  2. Article - Articles

The model is described in the file models.py

For the development of these models have been used to inherit from the built-in Django Class Model. And use the model of the user User, as specified in the articles of the author of the number of registered users on the site.

from django.db import models
from django.contrib.auth.models import User


Section model consists of:

  1. Title
  2. URL - is used for the formation of the addresses on the site, that is not stored absolute paths, as part of the path to the list
  3. Description - is displayed in the top of the page before the list of articles

Let's look at the implementation of the model code:

class Section(models.Model):
    class Meta:
        db\_table = "section"

    section\_title = models.CharField(max\_length=200)
    section\_url = models.CharField(max\_length=50)
    section\_description = TextField()

    def \_\_str\_\_(self):
        return self.section\_title

Meta class allows you to override some of the parameters of the model, which are directly related to the tables in the database. In this case determined, as will be called the Table.

The model has three fields, two of them have type CharField , which implies small recording limited number of input characters.

TextField type implies that there will be introduced a large enough random array of characters, the maximum size of which is not known beforehand.

Override __str__ , and this is an override and not the new method makes it possible to return the title of the article that will appear in the admin panel. The fact is that if this method is not overridden, then all records in admin page will look like Section Object, and to understand where and what is to be very problematic when a large number of sections.


The model consists of the following fields:

  1. Name
  2. Section - a foreign key to the Section table, determines the articles belonging to a particular section
  3. Author - a foreign key to the Users table from which will choose the author
  4. Date - date and time of publication
  5. Content - text field, similar to the description like in the Section model
  6. Status - I am assuming several statuses for articles currently used only two:
    1. Draft - the value 0
    2. Posted - the value 1
class Article(models.Model):
    class Meta:
        db\_table = "article"

    article\_title = models.CharField(max\_length=200)
    article\_section = models.ForeignKey(Section)
    article\_author = models.ForeignKey(User)
    article\_date = models.DateTimeField('Дата публикации')
    article\_content = TextField()
    article\_status = models.IntegerField()

    def \_\_str\_\_(self):
        return self.article\_title

Register models in the admin

In order to be able to edit articles and sections of the admin, you must register them in the admin module. This is done in admin.py relevant application file.

from django.contrib import admin

from .models import Section, Article



Wrote model, sure that the models have all the required fields? Then you need to make a database migration. To do this, execute the following commands.

python manage.py makemigrations
python manage.py migrate


Primary Key in the general case is entered automatically and is auto-increment, so we do not indicate it.


Templates Django's just a wonderful thing, especially when you consider that they can be inherited, and certain blocks will be overridden.

The project created a basic template base.html home application, from which all the other pages were inherited. Conditional template structure is as follows:

{% block head %}
{% endblock %}
{% block content %}
    {% block page %}
    {% endblock page %}
    {% block sidebar %}
    {% endblock %}
{% endblock content %}
{% block footer %}
{% endblock %}

In this case, there are five units, which can be overridden during inheritance patterns in other pages.


This template application's main page displays a list of all the sections. Use the extends statement, we specify that inherit from the base application template home. A duplicated page block of the base template, and prescribing the contents of this block we redefine the basic pattern making the information we need for a particular page.

As you can see, in the Django template language used the following constructions: if, for, url. But where did the variables section_list and section ? - Section_list passed as context values in a template in preparing the data in the presentation (view). After ensuring that there is a list of sections, we go through all the items in the list by substituting values into the template. Since the model section corresponds to Section, the corresponding fields of the model name are picked up automatically.

With regard to the url , then the operator indicates that it is necessary to take the address of the template knowledge application named section called, and we know that this address has a variable pattern, which we assign url object section. These templates are described in the file urls.py. We look at them later.

{% extends 'home/base.html' %}
{% block page %}
    {% if section\_list %}
        {% for section in section\_list %}
            <a href="{% url 'knowledge:section' section.section\_url %}">{{ section.section\_title }}</a>
        {% endfor %}
    {% endif %}
{% endblock %}


In the Template list, there is the formation of articles that match this razdlu. The context into the template variable section is transmitted, which contains information about the object section. We substitute the section title and description. Note that description is substituted with special argument safe, which indicates the format preservation. This must be done to save the html markup, otherwise the user will see instead a beautifully designed layout html code descriptions.

Also here it is a variant with a getting of information about all the articles that refer to this list, and this is done with the help of section.article_set.all call, that is, we take all the articles that have a foreign key to this section. Well, sort articles using dictsort specifying the parameter on which they are sorted.

A block if is checked the status of the article, that is, those items which are not published, will not be displayed.

With regard to the url , then again used the address template, but with two arguments.

{% extends 'home/base.html' %}
{% block page %}
    <h1>{{ section.section\_title }}</h1>
        <p>{{ section.section\_description|safe }}</p>
        {% for article in section.article\_set.all|dictsort:'article\_title' %}
            {% if article.article\_status %}
            <a href="{% url 'knowledge:article' section.section\_url article.id %}">
                {{ article.article\_title }}
            {% endif %}
        {% endfor %}
{% endblock %} 


As you can see, the template for the article meager enough to add something about it.

{% extends 'home/base.html' %}
{% block page %}
        <h1>{{ article.article\_title }}</h1>
        <p>{{ article.article\_content|safe }}</p>
{% endblock %}


If you look at the structure of the project, to see that the application contain more templates folder folders that have the same name as the application and page templates are already in them. This is done in order to accurately determine which template will be used. Django looks for templates in all folders and selects the first pattern that matches the name. And if the names are crossed, such as the index.html, the wrong template may be selected. Therefore namespace is used to determine what exactly the desired template.


In this case, the work with the presentation of sufficiently limited, so bring at once a full listing views.py file.

We inherit from the View class and override the method get, which is responsible for the execution of a GET request, that is, the user page request. We also import render_to_response methods, which will process the template in the required context, and get_object_or_404 , which will automatically return a 404 error if the object is found, the corresponding variable.

In EKnowledgeIndex we get everything Sections, which sorted by name and placed in the context of the name section_list, you remember that this variable was used in the template index.html .

In ESectionView already taken concrete section, the argument that is passed to the requested url. kwargs just responsible for variables that delaminate from the url of the template specified in the file urls.py.

In EArticleView everything is much more interesting. The fact that the two variables used url template, but for the article is enough to make a request for id, then have a Primary Key, which is passed to the url.

from django.views import View
from django.shortcuts import render\_to\_response, get\_object\_or\_404

from .models import *

class EKnowledgeIndex(View):
    template\_name = 'knowledge/index.html'

    def get(self, request, *args, **kwargs):
        context = {}
        context['section\_list'] = Section.objects.all().order\_by('section\_title')

        return render\_to\_response(template\_name=self.template\_name, context=context)

class ESectionView(View):
    template\_name = 'knowledge/section.html'

    def get(self, request, *args, **kwargs):
        context = {}
        section = get\_object\_or\_404(Section, section\_url=self.kwargs['section'])

        context['section'] = section

        return render\_to\_response(template\_name=self.template\_name, context=context)

class EArticleView(View):
    template\_name = 'knowledge/article.html'

    def get(self, request, *args, **kwargs):
        context = {}
        article = get\_object\_or\_404(Article, id=self.kwargs['article\_id'])

        context['article'] = article

        return render\_to\_response(template\_name=self.template\_name, context=context)

URL templates

Well, all that you need to write, but there was quite a bit to make it work, namely to configure url patterns, requests will be processed on that.

A feature of Django is that these templates are checking on regular expressions, and are not derived from models of controllers. For me personally, this approach proved to be clear and transparent, and I like him. So let's see how to revitalize our pages.


First we need to set patterns in mysite / mysite / urls.py file that will determine which application to send a request. Here you can see that there is a trend in home application, there is shown the main page of the site, but I will not go into a description of the parts because of it we do not speak in this article. There is also a trend in the admin site and application knowledge, which is responsible just for the sections and articles.

A include , connected urls.py files in the home and knowledge applications.

from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^', include('home.urls')),
    url(r'^knowledge/', include('knowledge.urls')),
    url(r'^admin/', admin.site.urls),


app_name is responsible for the namespace in the templates. Remember? Just above the template was recording 'knowledge: section'

Well, regular expressions define what and where will be sent. With regard to records

, then these are the variables that get processed in the method in the submissions and transmitted via kwargs .

Well, name specifies a URL template name, that is the second part in the 'knowledge: section' .

And finally, I would like to note is the ^ symbol, which is present in the template. With it has discarded the recognized part of the template. That is, in these url is also present in the early knowledge /, which was previously recognized in mysite / mysite / urls.py.

from django.conf.urls import url

from . import views

app\_name = 'knowledge'
urlpatterns = [
    url(r'^$', views.EKnowledgeIndex.as\_view(), name='index'),
    url(r'^(?P<section>[\w]+)/$', views.ESectionView.as\_view(), name='section'),
    url(r'^(?P<section>[\w]+)/(?P<article\_id>[0-9]+)/$', views.EArticleView.as\_view(), name='article')

For Django I recommend VDS-server of Timeweb hoster .

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.

Спасибо за ваши статьи. Очень понятно и качественно пишите. Есть пара моментов в  данной статье, которые мне кажутся спорными. Например, именование полей внутри моделей(article_title, article_date вместо просто title и date). Думаю добавлять в качестве префикса имя модели несколько избыточно - поля без модели не используются и без всяких префиксов всегда понятно откуда они. Второй момент это использование в шаблоне для ссылки на конкретный объект тег url. Гораздо удобнее реализовать для модели метод get_absolute_url и использовать его. Это даст возможность полностью менять схему урлов без поиска и переписывания всех шаблонов. К тому же этот метод используется стандартной админкой для формирования ссылок "посмотреть на сайте". Ну и ваши представления легче было наследовать от соответсвующих generic views - DetailView, ListView.
Хотя может это всё допущения чтобы не усложнять материал.

Спасибо за отзыв.

По факту согласен со всеми вашими примечаниями.
Но это действительно допущения, чтобы не перегружать материал всем подряд. А так да, активно пользуюсь get_absolute_url и дженериками . В одной статье есть и про дженереки информация.

Хотелось спросить, можно ли создать многоуровневые url из свойств модели? Я вот с часик лежал, искал как это сделать не нашел, вопрос на хабре оставил, никто не ответил. Оригинальная документация говорит только об одном слаге, а все примеры заканчиваются на том, что есть домен и к нему slug. Я просто хотел прикрепить запись к определенной категории, и еще одной субкатегории, т.е типо домен/категория/подкатегории/запись
я сделал подобное, но блин, доступ к записи осуществляется даже с др.категории и вообще с любимым текстом, т.е ссылка каноническая, могу перейти и по test/test/запись и по nowork/test/запись, передавал в модель свойства вот так: kwargs=("url":self.url, "cat":self.cat.url, "sub":self.sub.url)

Если я правильно понимаю ваш вопрос, то нечто подобное у меня реализовано для страниц правил пользования сайтом, вот например страница тем форума

Но там я формирую полный путь, укладываю его в slug, а вот url шаблон у меня сделан так

path('<path:slug>/', PageView.as_view(), name='page')

Но у меня реализация там сделана за счёт того, что я задаю частичный url, который собирает все parent страницы формирует уже итоговый url и кладёт его куда надо.

Ещё делал раньше как вы делаете, но я так полагаю, что у вас код смотреть нужно, наверняка у вас неправильно написан код где-то:

  • или метод get_absolute_url
  • или url диспетчера.
  • или не выкидываете ошибку 404 по View, если из сформированного url не удаётся найти объект.

К слову говоря, если делали по этой статье, то там тоже в EArticleView нужно ещё добавить проверку на slug раздела, и если не совпадаетЮ, то выкинуть ошибку 404. Так что да, косяк в статье.

Я делаю вот так у себя в модели для получения ссылки:
Там где доработать это я закомментил, ибо получалось доступность по всем категориям, потом выяснил, что так вообще по всей ссылки.


# Формируем URL
    def get_absolute_url(self):
        #games = self.games.all()[0] доработь 'games': games.url, ->
        return reverse('article_detail', kwargs={'category': self.category.url, 'slug': self.url})


# Полная статья
class ArticleDetail(DetailView):
    model = Article
    slug_field = "url"


path('articles/<category>/<slug>/', views.ArticleDetail.as_view(), name="article_detail"),

Запись доступна по articles/blog/название статьи, но таким же образом она доступна к неподвязанной категории, т.е articles/files/название статьи
Также можно любой текст можно подставить, articles/131411414/название статьи и будет тоже доступно.

Ну я так и думал. Здесь нужно или обычный View использовать, или формировать slug так, чтобы он содержал slug категории, и как у меня использовать path, но тут тогда будет проблем в том, что тогда url категории скорее всего перестанет работать.

Так что или берите обычный View, добавляйте туда метод get, и проверяйте как slug статьи, так и slug категории, которая будет привязана к статье, либо переопределяйте метод get_object у DetailView, но там также нужно будет ковырять как slug статьи, так и slug категории

Хорошо, посмотрю что получится с простым View


Отлично. Спасибо. Вопрос, как мне теперь передать на индексную страницу(ту которая по умолчанию) содержание только статей, без секций? И вообще передать на дефолтную страницу? Что то не получается. PS: в джанго - недавно, неделю.


Я дура. Разобралась. Но, остаюсь вашим читателем)

from django.shortcuts import *
from django.http import *
from django.http import HttpResponseRedirect
from django.contrib.auth.forms import *
from django.urls import reverse_lazy
from django.views import generic
from django.views.generic import *
from .models import Post

# Create your views here.
def index(request):
    postview = Post.<- а object отсуствует?
    return render(request,'index.html')
def about(request):
    return render(request,'about.html')
def contact(request):
    return render(request,'contact.html')
def home (request):
    return render(request, 'home/index.html')
class SignUpView(generic.CreateView):
    form_class = UserCreationForm
    success_url = reverse_lazy('login')
    template_name = 'signup.html'


отсутствует object


Only authorized users can post comments.
Please, Log in or Sign up

Let me recommend you a great European Fornex hosting.

Fornex has proven itself to be a stable host over the years.

For Django projects I recommend VPS hosting

Following the link you will receive a 5% discount on shared hosting services, dedicated servers, VPS and VPN

View Hosting

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:50points,
  • Rating points-4

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:50points,
  • Rating points-4

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:20points,
  • Rating points-10
Popular publications in the last 90 Days
Last comments

Qt/C++ - Lesson 005. QSqlRelationalTableModel - The work with relational tables

Хочу поделится, мы сделали свой вариант QSqlRelationalTableModel и заодно к нему новое развитие QTableView, и получилась готовая таблица PblTableDlg, у которой реализованы внешние связи, комбобо…

Qt WinAPI - Lesson 004. QtIFW - Automation WinDeployQt and build installers with Qt Installer Framework

Hello Evgenij, regarding the online installer, I've tried many times to use web host for the created repo after repogen step. I tried using github but I found people talking it is not …
  • juvf
  • Jan. 16, 2023, 10:18 p.m.

Qt/C++ - Lesson 051. QMediaPlayer – simple audio player

PS. Почти дописал плеер на QML. Уперся в ограничения QML. Переписываю плеер на с++/qt, а графика останится в qml. Нашел то, что мне надо, а именно индикатор звука. Qt может перехватывать аудиопо…

Qt/C++ - Lesson 039. How to paint stroke in QSqlTableModel by value in the column?

В этом случае вижу только какой-нибудь костыль в стиле перебора по всем индексам в заголовке с помощью методу headerData . То есть пройтись в for цикле пока не будет совпадения н…
  • avt
  • Dec. 12, 2022, 9:06 a.m.

Qt/C++ - Lesson 039. How to paint stroke in QSqlTableModel by value in the column?

Спасибо за ответ. Нет, дело не в читаемости кода, в разных таблицах у меня есть столбцы с одинаковым именем, но с разными индексами. Хотел сделать решение по имени столбца для всех таблиц сразу.…
Now discuss on the forum

django rest framework лишние символы

Покажите код сериализатора вашего.

Здравствуйте помогите с qml

нужно высчитывать координаты того, что должно двигаться, полагаю, что тот маленький круг, и в случае выхода за пределы круга менять переменную типа bool на true/false, которая в свою очередь буд…
  • BlinCT
  • Jan. 30, 2023, 11:59 a.m.

Обращение к сигналу из qml который реализован в другом потоке

Хотя есть мысль что я не правильно создаю реакцию на данный сигнал. Но вроде как правильно все.

Как добавить виртуальную клавиатура с Т9 в своей проект на QML.

Добрый день. Прошу помочь, пишу небольше приложение в Qt. Добвил в свой проект виртуальную клавиатуру от Qt. Но как добавить в него возможность изменения Т9 никак не могу понять.
© EVILEG 2015-2022
Recommend hosting TIMEWEB