Как сделать ширину полей ввода одинаковой между собой в django-crispy-forms?

Я переписываю свой сайт на Django и хотел бы использовать формы Django, так как это действительно проще, чем писать каждую форму вручную в HTML. Я просмотрел документацию по crispy-forms и обнаружил, что есть нечто, называемое Layout. Я не знаю, использую ли я его по назначению или повторяюсь снова и снова, но вот что у меня получилось:

from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Fieldset, Submit, HTML, Div
from django import forms

from .models import Member


class EnrollForm(forms.ModelForm):
    message = forms.CharField(widget=forms.Textarea)

    def __init__(self):
        super().__init__()
        self.helper = FormHelper()
        self.helper.form_show_labels = False
        self.helper.layout = Layout(
            Fieldset(
                '',
                input_with_icon('bi bi-person', 'first_name'),
                input_with_icon('bi bi-person', 'last_name'),
                input_with_icon('bi bi-123', 'student_id'),
                input_with_icon('bi bi-building', 'department'),
                input_with_icon('bi bi-list-ol', 'degree'),
                input_with_icon('bi bi-envelope', 'email'),
                input_with_icon('bi bi-telephone', 'mobile_number'),
                input_with_icon('bi bi-chat-left-text', 'group_chat_platform'),
                input_with_icon('bi bi-send', 'message'),
            ),
            Submit('submit', 'Üye Ol', css_id='signup-btn')
        )

    class Meta:
        model = Member
        fields = ['first_name',
                  'last_name',
                  'student_id',
                  'department',
                  'degree',
                  'email',
                  'mobile_number',
                  'group_chat_platform']


def input_with_icon(icon_class, field_name):
    return Div(
        Div(
            HTML(
                f"""<span class="m-3">
                    <i class="{icon_class} fs-2" style="color: #ff4100;"></i>
                </span>"""
            ),
            css_class='input-group-prepend'
        ),
        field_name,
        css_class='input-group mb-3'
    )
{% extends "base/boilerplate.html" %}
{% load crispy_forms_tags %}
{% block content %}
    <div class="container-sm align-items-center">
        <div class="py-2 mt-4 align-items-center">
            <div class="ml-5 pt-3 align-items-center form-container">
                <h1 class="text-center mb-5">Topluluğumuza Katılın</h1>
                <form method="POST" enctype="multipart/form-data" style="max-width: 40%; margin: 0 auto;">
                    {% crispy form %}
                </form>
            </div>
        </div>
    </div>
{% endblock content %}

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

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

Да, вы правильно используете макет. Я предпочитаю не загромождать __init__ формы множеством строк, а поместить компоновку в функции в том же файле, что и форма, и сделать вот так. Это чисто стилистическое решение.

def get_whatever_layout():
    return Layout(
        ...
    )

class ...
    def __init__(self):
        super().__init__()
        self.helper = FormHelper()
        self.helper.layout = get_whatever_layout(
<<<Стилизация элементов

<input> и <select> в CSS - та еще морока, но это то, что вам нужно. Crispy позволит вам добавить классы для определения элементов. Ваши <input> имеют одну ширину (по умолчанию?), ваши <select> - другую.

Я нахожу браузер Firefox очень полезным для экспериментов. Вы можете щелкнуть правой кнопкой мыши и "проинспектировать", затем добавить или удалить атрибуты CSS(?), пока не добьетесь того, что работает. Затем добавьте его в таблицу стилей.

Мой пример (для Crispy MultiField с css_class="multi-wide"...)

 div.multi-wide div.range-field input { width: 18em; }

Вам может понадобиться !important, или высокая специфичность, чтобы "победить", если bootstrap или другой фреймворк пытается управлять этими элементами за вас. Firefox покажет вам, откуда взяты текущие настройки элемента.

Вернуться на верх