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

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

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

 Следующим шагом нам нужно стилизовать нашу страницу профилей, для этого откроем шаблон profile.html и внесем изменения: 

{% extends "blog/base.html" %}
{% block title %}Profile Page{% endblock title %}
{% block content %}
    <div>
        <img src="{{ user.profile.avatar.url }}"/>
    </div>
    {% if user_form.errors %}
        <div class="container d-flex align-items-center justify-content-center">
            <div class="alert alert-warning alert-dismissible fade show w-50  d-block" role="alert">
                {% for key, value in user_form.errors.items %}
                    <strong>{{ value }}</strong>
                {% endfor %}
                <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
            </div>
        </div>
    {% endif %}
    <div class="form-content">
        <form method="post" enctype="multipart/form-data">
            {% csrf_token %}
            <div>
                <div>
                    <div>
                        <label>Username:</label>
                        {{ user_form.username }}
                        <hr>
                        <label>Email:</label>
                        {{ user_form.email }}
                    </div>
                    <hr>
                    <div><a href="{% url 'password_change' %}">Change Password</a>

                        <hr>
                        <label>Change Avatar:</label>
                        {{ profile_form.avatar }}
                    </div>
                    <hr>
                    <label>Bio:</label> {{ profile_form.bio }}
                </div>
            </div>
            <button type="submit" class="btn btn-primary btn-lg">Save Changes</button>
            <button type="reset" class="btn btn-primary btn-lg">Reset</button>
        </form>
    </div>
{% endblock content %}

Далее нам нужно добавить стили к нашим полям формы, для этого обновим UpdateUserForm и UpdateProfileForm:

class UpdateUserForm(forms.ModelForm):
    username = forms.CharField(max_length=100,
                               required=True,
                               widget=forms.TextInput(attrs={"class": "form-control mb-1", 'placeholder': 'Username'}))
    email = forms.EmailField(required=True,
                             widget=forms.TextInput(attrs={"class": "form-control mb-1", 'placeholder': 'Email'}))

    class Meta:
        model = User
        fields = ['username', 'email']


class UpdateProfileForm(forms.ModelForm):
    avatar = forms.ImageField(widget=forms.FileInput(attrs={"class": "form-control mb-1"}))
    bio = forms.CharField(widget=forms.Textarea(attrs={"class": "form-control"}))

    class Meta:
        model = Profile
        fields = ['avatar', 'bio']

Проверим результат:

И напоследок у нас осталось изменить форму изменения пароля change_password.html, для этого:

{% extends "blog/base.html" %}
{% block content %}
    <h3>Change Your Password</h3>
    {% if form.errors %}
        <div class="container d-flex align-items-center justify-content-center">
            <div class="alert alert-warning alert-dismissible fade show w-50  d-block" role="alert">
                {% for key, value in form.errors.items %}
                    <strong>{{ value }}</strong>
                {% endfor %}
                <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
            </div>
        </div>
    {% endif %}
    <form method="POST">
        {% csrf_token %}
        <label>Old Password</label>
        <input type="password" class="form-control mb-1" name="old_password" autocomplete="new-password" required
               id="id_old_password"
               placeholder="Enter Old Password"/>
        <label>New Password</label>
        <input type="password" class="form-control mb-1" name="new_password1" autocomplete="new-password"
               required id="id_new_password1"
               placeholder="Enter New Password"/>
        <label for="id_new_password2">New Password Confirmation</label>
        <input type="password" class="form-control mb-1" name="new_password2" autocomplete="new-password"
               required id="id_new_password2" placeholder="Confirm New Password"/>
        <button type="submit" class="btn btn-primary btn-lg" id="reset">Update Password</button>
    </form>
{% endblock content %}

В данный шаблон мы также добавили модальное окно для индикации ошибок при заполнении формы.

Проверим работу:

На этом всё, в рамках данного курса, мы не будем тратить время на добавление стилей к страницам типа password_reset_*****.html.

Наша основная задача была показать как легко подключить Bootstrap 5 к проекту Django и использовать его по вашему желанию.


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

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

password_change.html (только форма):

    <form method="POST">
        {% csrf_token %}

        <div class="form-floating mb-1">
            <input type="password" class="form-control mb-1" name="{{ form.old_password.name }}"
                   autocomplete="new-password" required id="{{ form.old_password.id_for_label }}" placeholder=""/>

            <label for="{{ form.old_password.id_for_label }}">{{ form.old_password.label }}</label>
        </div>
        <div class="form-floating mb-1">
            <input type="password" class="form-control mb-1" name="{{ form.new_password1.name }}"
                   autocomplete="new-password" required id="{{ form.new_password1.id_for_label }}" placeholder=""/>

            <label for="{{ form.new_password1.id_for_label }}">{{ form.new_password1.label }}</label>
        </div>
        <div class="form-floating mb-1">
            <input type="password" class="form-control mb-1" name="{{ form.new_password2.name }}"
                   autocomplete="new-password" required id="{{ form.new_password2.id_for_label }}" placeholder=""/>

            <label for="{{ form.new_password2.id_for_label }}">{{ form.new_password2.label }}</label>
        </div>

        <button type="submit" class="btn btn-primary btn-lg mt-1">Update Password</button>
    </form>

Выглядит вот так:

Заодно и профиль отрисовал аналогично по стилю плюс и два столбца. Не уверен, что это правильный выбор, но захотелось попробовать. Подробностями утомлять не буду:

placeholder у аватара от username "затесался", он там явно лишний

class UpdateProfileForm(forms.ModelForm):
    avatar = forms.ImageField(widget=forms.FileInput(attrs={"class": "form-control mb-1", 'placeholder': 'Username'}))

@ilya_kutaev, спасибо, поправил.

Поправьте  тут пожалуйста, а то не понятно какую форму надо менять!

change_password.html

И напоследок у нас осталось изменить форму изменения пароля, для этого:

{% extends "blog/base.html" %}
{% block content %}
    <h3>Change Your Password</h3>
    {% if form.errors %}
        <div class="container d-flex align-items-center justify-content-center">
            <div class="alert alert-warning alert-dismissible fade show w-50  d-block" role="alert">
                {% for key, value in form.errors.items %}
                    <strong>{{ value }}</strong>
                {% endfor %}
                <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
            </div>
        </div>

@No_Name, спасибо, добавил.

зачем UpdateUserForm и UpdateProfileForm   разделены по разным классам? Наследуются ведь от одного и того же

У них разные модели.