Django 5 для начинающих

Прогресс по курсу:  9/1004

7.6 Улучшаем дизайн блога с использованием Bootstrap 5
7 из 7 шагов пройдено

Следующим шагом мы изменим отображение нашего поиска http://127.0.0.1:8000/search/, для этого в приложении blog откроем наши формы - forms.py и изменим отображение запроса поиска:

class SearchForm(forms.Form):
    query = forms.CharField(
        widget=forms.TextInput(attrs={"class": "form-control mb-1", 'placeholder': 'Enter search term...'}))

К полю query мы добавили виджет, к которому же добавили нужный класс стиля и текстовую подсказку.

Теперь откроем шаблон нашего поиска, search.html и внесем правки:

{% extends "blog/base.html" %} {% load blog_tags %}

{% block title %}Search{% endblock %}

{% block content %} {% if query %}
    <h1>
        Posts containing "{{ query }}"
    </h1>
    <h3>
        {% with results.count as total_results %}
            Found {{ total_results }} result{{ total_results|pluralize }} {% endwith %}
    </h3>
    <hr class="mt-1 mb-1"/>
    {% for post in results %}
        <h4>
            <a href="{{ post.get_absolute_url }}"> {{ post.title }}
            </a>
        </h4>
        {{ post.body|markdown|truncatewords_html:12 }} {% empty %}
        <p>There are no results for your query.</p>
    {% endfor %}
    <p><a href="{% url "blog:post_search" %}">Search again</a></p> {% else %}
    <h1>
        Search for posts
    </h1>
    <form method="get">
        {{ form.query }}
        <input type="submit" value="Search" class="btn btn-primary mb-3 btn-lg">
    </form>
{% endif %} {% endblock %}

Проверим отображение нашего поиска:

И в завершении стилизации нашего приложения blog, нам необходимо изменить форму и шаблон нашей возможности
Share a post, для этого снова откроем наши формы и изменим вывод, добавив нужные атрибуты:

class EmailPostForm(forms.Form):
    name = forms.CharField(max_length=25, required=True, widget=forms.TextInput(attrs={"class": "form-control mb-1", 'placeholder': 'Name'}))
    email = forms.EmailField(required=True, widget=forms.TextInput(attrs={"class": "form-control mb-1", 'placeholder': 'E-Mail'}))
    to = forms.EmailField(required=True, widget=forms.TextInput(attrs={"class": "form-control mb-1", 'placeholder': 'To'}))
    comments = forms.CharField(required=False,
                               widget=forms.Textarea(attrs={"class": "form-control mb-1", 'placeholder': 'Comments'}))

Далее отредактируем шаблон share.html:

{% extends "blog/base.html" %}

{% block title %}Share a post{% endblock %}

{% block content %}
    {% if sent %}
        <h1>E-mail successfully sent</h1>
        <p>
            "{{ post.title }}" was successfully sent
            to {{ form.cleaned_data.to }}.
        </p>
    {% else %}
        <h1>Share "{{ post.title }}" by e-mail</h1>
        <form method="post">
            {{ form.name }}
            {{ form.email }}
            {{ form.to }}
            {{ form.comments }}
            {% csrf_token %}
            <input type="submit" value="Send e-mail" class="btn btn-primary mb-3 btn-lg">
        </form>
    {% endif %}
{% endblock %}

В данном шаблоне мы убрали заголовки полей ввода, и изменили стиль отображения кнопки Send e-mail. Проверим работу:

В следующем разделе мы продолжим доработку нашего проекта, а именно добавление стилей к нашему приложению accounts.


  • Комментария
Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Оставить комментарий

перешел сейчас на страницу поиска и получилась такая картина, подвал оказался не в самом низу, это с чем может быть связано? При том, что на главной странице блога или на странице любого поста все ок

@Георгий_Тимофеев, Скорее всего не хватает высоты контента у боди. Попробуйте добавить в боди класс:

<body class="d-flex flex-column min-vh-100">

А в футеру добавим класс mt-auto

<footer class="py-5 bg-dark mt-2 mt-auto">

@Илья_Перминов, это помогло, спасибо. А как это работает, что мы добавили?

@Илья_Перминов, добавил в лекцию.

@Георгий_Тимофеев, Мы добавляем в боди:

  • d-flex: превращаем элементы в флекс-контейнер, что позволяет управлять расположением дочерних элементов внутри него.
  • .flex-column для установки вертикального направления у контейнеров
  • .min-vh-100 минимальная высота 100% экрана браузера

А у футера мы добавляем mt-auto, что по простому margin-top: auto

На самом деле у Bootstrap огромные возможности, можете посмотреть их в документации с примерами.

Получилось сделать плавающие метки полей, как описано здесь: https://getbootstrap.com/docs/5.2/forms/floating-labels/

Используются именно значения атрибута label поля. При этом placeholder в виджете должен быть задан, но может быть пустым - его значение не используется. Если его не задать, метка будет всегда наверху. Немного странно...

Когда начинаешь вводить значение, метка "отплывает" наверх:

Все довольно просто - приложу только форму из share.html:

        <form method="post">
            {% csrf_token %}
            {% for field in form %}
                <div class="form-floating mb-1">
                {{ field }}
                <label for="{{ field.id_for_label }}">{{ field.label }}</label>
                </div>
            {% endfor %}
            <input type="submit" value="Send e-mail" class="btn btn-primary mb-3 btn-lg">
        </form>

Видимо, можно использовать стандартный рендер с помощью as_div(), которой нужно "подсунуть" правильный шаблон вместо 'django/forms/div.html' - как описано в документации, но я не стал так сильно заморачиваться, здесь проще цикл в шаблоне написать

Изменен ilya kutaev