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

view, model, template

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:

mysite/
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        wsgi.py
    home/
        __init__.py
        admin.py
        apps.py
        models.py
        tests.py
        urls.py
        views.py
        templates/
            home/
                base.html
    knowledge/
        __init__.py
        admin.py
        apps.py
        models.py
        tests.py
        urls.py
        views.py
        templates/
            knowledge/
                article.html
                index.html
                section.html

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.

INSTALLED_APPS = [
    'home.apps.HomeConfig',
    'accounts.apps.AccountsConfig',
    ...
]

Model

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

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.

Article

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

admin.site.register(Section)
admin.site.register(Article)

Migration

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

Note

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

Templates

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.

index.html

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 %}
    <article>
    <h1>Разделы</h1>
    {% if section_list %}
        <ul>
        {% for section in section_list %}
            <li>
            <a href="{% url 'knowledge:section' section.section_url %}">{{ section.section_title }}</a>
            </li>
        {% endfor %}
        </ul>
    {% endif %}
    </article>
{% endblock %}

section.html

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 %}
    <article>
    <h1>{{ section.section_title }}</h1>
        <p>{{ section.section_description|safe }}</p>
        <h2>Статьи</h2>
        <ul>
        {% for article in section.article_set.all|dictsort:'article_title' %}
            {% if article.article_status %}
            <li>
            <a href="{% url 'knowledge:article' section.section_url article.id %}">
                {{ article.article_title }}
            </a>
            </li>
            {% endif %}
        {% endfor %}
        </ul>
    </article>
{% endblock %} 

article.html

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

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

Note

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.

View

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.

mysite/mysite/urls.py

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),
]

mysite/knowledge/urls.py

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 <section> and <article_id> , 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.
Support the author Donate
PK

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

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

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

Comments

Only authorized users can post comments.
Please, Log in or Sign up
Looking for a Job?
14,000.00 руб. - 40,000.00 руб.
Разработчик Qt
Annino, Moscow Oblast, Russia
5,000.00 руб. - 15,000.00 руб.
Дизайнер
Moskovskiy, Moscow, Russia
25,000.00 руб. - 30,000.00 руб.
Разработчик Qt/C++
Barnaul, Altai Krai, Russia

For registered users on the site there is a minimum amount of advertising

A
Aug. 22, 2019, 11:24 p.m.
Aleksandr73

Qt - Test 001. Signals and slots

  • Result:47points,
  • Rating points-6
Aug. 21, 2019, 10:23 a.m.
Andrej Ermoshin

C++ - Test 002. Constants

  • Result:58points,
  • Rating points-2
Aug. 21, 2019, 10:15 a.m.
Andrej Ermoshin

C++ - Test 001. The first program and data types

  • Result:86points,
  • Rating points6
Last comments
Aug. 19, 2019, 7:41 a.m.
Andrej Jankovich

это проблема дистрибутива, попробуйте установить через пакетный менеджер snap Суть проблемы: libQt5Core которая лежит в дистрибутиве требует версию glibc >= 2.25 у вас видимо …
b
Aug. 18, 2019, 6:09 a.m.
bbb116

cqtdeployer /home/aleks/CQtDeployer/bin/cqtdeployer: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.25' not found (required by /home/aleks/CQtDeployer/lib/libQt5Core.so.5) linux mint …
D
Aug. 17, 2019, 9:04 a.m.
Damir

github ChekableTView Правой групповая смена значения при перетаскивании левой как обычно.
Aug. 16, 2019, 1:03 p.m.
Evgenij Legotskoj

Потому, что в минуте 60 секунд
Aug. 16, 2019, 12:16 p.m.
Dmitrij

а почему делитель 60000, а не 1000?
Now discuss on the forum
Aug. 24, 2019, 7:21 a.m.
Evgenij Legotskoj

Не помню, давно уже с QML не работал, по-моему, обычно пишет в консоль, что не находит файл. В любом случае какую-то ошибку в консоль выкидывает. Но если честно, если у вас проект будет ак…
BG
Aug. 24, 2019, 4:27 a.m.
Brjus Gliff

Спасибо, вначале в документации было не понятно что к чему, теперь разобрался
I
Aug. 21, 2019, 8:36 a.m.
Intruder

Александр, мне не нужно перебирать. Вы говорите правильно, сначала я написал избыточный код просто не подумав. Задача такая, мне нужно просто переложить из QMap в атрибуты xml тега все, что там …
Aug. 21, 2019, 3:16 a.m.
nayk1982

Если Вы разрабатываете какую-то универсальную утилиту, которая вообще не привязана к логике, тогда как вариант: 1. Получить список таблиц через QSqlDatabase::tables 2. Для каждой табли…
EVILEG
About
Services
© EVILEG 2015-2019
Recommend hosting TIMEWEB