В качестве хобби, я решил открыть для себя мир веб-разработки, попутно освещая свои успехи, а может и неудачи на пути к просветлению…

В настоящее время я публично описываю процесс создания веб-сайта с нуля на Django и Bootstrap, где задача разработать такие приложения как: аккаунты, вопросы, статьи и книги.

В проекте решаются только реальные задачи, которые почему-то так любят обходить стороной в учебной литературе.

Создание веб-сайта с нуля на Django и Bootstrap. Вопросы. Список вопросов и ответов к ним. Шаблоны

Сергей Серов

Шаблоны

Переходим в директорию шаблонов проекта и создаем там каталог с названием questions.

Шаблон списка вопросов

В подкаталоге создаем файл с названием index.html:

{% extends 'base.html' %}

{% block title %}Вопросы{% endblock %}

{% block main %}
    <div class="questions-index">
        {% if questions %}
            <h1>
                Вопросы
                <a href="{% url 'questions:feed' %}">
                    <span class="sr-only">Лента последних вопросов</span>
                    <i class="fa fa-rss fa-fw" aria-hidden="true"></i>
                </a>
            </h1>

            {% for question in questions %}
                <div class="question">
                    <div class="row">
                        <div class="col-sm-3">
                            <time class="created" datetime="{{ question.created|date:'c' }}">{{ question.created|date }}</time>
                        </div>

                        <div class="col-sm-1">
                            {% if question.answered %}
                                {% if question.answered < question.updated %}
                                    <i class="fa fa-check-square fa-lg" aria-hidden="true" style="color: darkorange"></i>
                                {% else %}
                                    <i class="fa fa-check-square fa-lg" aria-hidden="true" style="color: darkgreen"></i>
                                {% endif %}
                            {% else %}
                                <i class="fa fa-question-circle fa-lg" aria-hidden="true" style="color: darkred"></i>
                            {% endif %}
                        </div>

                        <div class="col-sm-8">
                            <h2 class="title">
                                <a href="{{ question.get_absolute_url }}">{{ question.title }}</a>
                            </h2>
                        </div>
                    </div>
                </div>
            {% endfor %}

            {% if questions.has_other_pages %}
                <nav aria-label="Навигация по страницам">
                    <ul class="pagination">
                        {% for page in questions.paginator.page_range %}
                            <li{% if page == questions.number %} class="active" aria-label="Текущая страница"{% endif %}>
                                <a href="?page={{ page }}">{{ page }}</a>
                            </li>
                        {% endfor %}
                    </ul>
                </nav>
            {% endif %}
        {% else %}
            <h1>Невероятно, но вопросов нет, похоже работа по ликбезу принесла свои плоды...</h1>
        {% endif %}

        <div class="your-question">
            <h2>Ваш вопрос</h2>

            {% if form %}
                <form action="{% url 'questions:index' %}" method="post">
                    {{ form.media }}
                    {% csrf_token %}
                    {% include 'core/form_fields.html' %}
                    <button type="submit" class="btn btn-success">Добавить</button>
                </form>
            {% else %}
                <div class="text">
                    <p><a href="{% url 'accounts:login' %}">Войдите</a>, чтобы задать Ваш вопрос...</p>
                </div>
            {% endif %}
        </div>
    </div>
{% endblock %}

Напротив каждого вопроса мы указываем его статус.

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

Статусы позволят быстрее ориентироваться в потоке вопросов.

Шаблон ответов на вопрос

В подкаталоге создаем файл question.html со следующим содержимым:

{% extends 'base.html' %}

{% block title %}{{ question.title }}{% endblock %}

{% block main %}
    <div class="questions-question">
        <h1 class="title">{{ question.title }}</h1>

        {% for article in question.articles %}
            <div id="article-{{ article.pk }}" class="article{% if article.is_answer %} answer{% endif %}">
                <address class="author">{{ article.author }}</address>

                {% if article.is_answer %}
                    <span class="label label-success expert">Ответ эксперта</span>
                {% endif %}

                <time class="created" datetime="{{ article.created|date:'c' }}">{{ article.created|date }}</time>

                {% if user.is_superuser %}
                    <a href="{{ article.get_admin_url }}">Редактировать</a>
                {% endif %}

                <div class="text">
                    {{ article.text|safe }}
                </div>
            </div>
        {% endfor %}

        <div class="your-answer">
            <h2>Ваш ответ</h2>

            {% if form %}
                <form action="{{ question.get_absolute_url }}" method="post">
                    {{ form.media }}
                    {% csrf_token %}
                    {% include 'core/form_fields.html' %}
                    <button type="submit" class="btn btn-success">Добавить</button>
                </form>
            {% else %}
                <div class="text">
                    <p><a href="{% url 'accounts:login' %}">Войдите</a>, чтобы написать ответ...</p>
                </div>
            {% endif %}
        </div>
    </div>
{% endblock %}

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

Базовый шаблон проекта

Для удобства навигации нам необходимо добавить ссылки на разделы сайта, редактируем базовый шаблон проекта следующим образом:

{% load static %}
<!DOCTYPE html>
<html lang="ru">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <meta name="author" content="{{ SITE_AUTHOR }}">

        <title>{% block title %}{% endblock %} | {{ SITE_TITLE }}</title>

        <link rel="alternate" type="application/atom+xml" title="{{ SITE_TITLE }}" href="{% url 'articles:feed' %}">

        <!-- Bootstrap -->
        <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
        <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">

        <!-- Style -->
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
        <link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700%7CUbuntu:700&amp;subset=cyrillic" rel="stylesheet">
        <link rel="stylesheet" href="{% static 'style.css' %}">

        <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
        <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
        <!--[if lt IE 9]>
            <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
            <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
        <![endif]-->

        <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
        <!-- Include all compiled plugins (below), or include individual files as needed -->
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
    </head>
    <body>
        <header>
            <nav class="navbar navbar-default navbar-static-top">
                <div class="container">
                    <div class="navbar-header">
                        <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse" aria-expanded="false">
                            <span class="sr-only">Переключить навигацию</span>
                            <span class="icon-bar"></span>
                            <span class="icon-bar"></span>
                            <span class="icon-bar"></span>
                        </button>
                        <a class="navbar-brand" href="/">serov.es</a>
                    </div>

                    <div class="collapse navbar-collapse" id="navbar-collapse">
                        <ul class="nav navbar-nav">
                            <li><a href="{% url 'articles:index' %}">Статьи</a></li>
                            <li><a href="{% url 'questions:index' %}">Вопросы</a></li>
                        </ul>

                        <ul class="nav navbar-nav navbar-right">
                            {% if user.is_authenticated %}
                                <li class="dropdown">
                                    <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
                                        <i class="fa fa-user fa-fw" aria-hidden="true"></i>
                                        {{ user.username }}
                                        <span class="caret"></span>
                                    </a>
                                    <ul class="dropdown-menu">
                                        <li>
                                            <a href="{% url 'accounts:change_password' %}">
                                                <i class="fa fa-key fa-fw" aria-hidden="true"></i>
                                                Смена пароля
                                            </a>
                                        </li>

                                        <li>
                                            <a href="{% url 'accounts:change_email' %}">
                                                <i class="fa fa-envelope-o fa-fw" aria-hidden="true"></i>
                                                Смена почты
                                            </a>
                                        </li>

                                        <li><a href="{% url 'accounts:logout' %}">
                                            <i class="fa fa-sign-out fa-fw" aria-hidden="true"></i>
                                            Выход
                                        </a></li>
                                    </ul>
                                </li>
                            {% else %}
                                <li>
                                    <a href="{% url 'accounts:login' %}">
                                        <i class="fa fa-sign-in fa-fw" aria-hidden="true"></i>
                                        Войти
                                    </a>
                                </li>
                            {% endif %}
                        </ul>
                    </div>
                </div>
            </nav>

            <div class="container">
                <div class="about">
                    <div class="row">
                        <div class="col-sm-8">
                            <h2 class="title"><a href="/">{{ SITE_TITLE }}</a></h2>
                            <h3 class="subtitle">{{ SITE_SUBTITLE }}</h3>
                        </div>

                        <div class="col-sm-4">
                            <address class="contacts">
                                <div class="mail">
                                    <span class="sr-only">Адрес электронной почты</span>
                                    <i class="fa fa-envelope-o fa-fw" aria-hidden="true"></i>
                                    Почта
                                </div>

                                <div class="location">
                                    <span class="sr-only">Местоположение</span>
                                    <i class="fa fa-globe fa-fw" aria-hidden="true"></i>
                                    Местоположение
                                </div>
                            </address>
                        </div>
                    </div>

                    <div class="description">
                        <p>
                            В течение десяти лет работы на крупных производственных предприятиях заполучил опыт создания служб с нуля,
                            по направлениям: охрана труда, пожарная, промышленная и экологическая безопасность.
                        </p>

                        <p>
                            Проведу для Вас полный аудит или разработаю комплекты документов по всем вышеперечисленным направлениям.
                        </p>
                    </div>
                </div>
            </div>
        </header>

        <main>
            <div class="container">
                {% block main %}{% endblock %}
            </div>
        </main>
    </body>
</html>