row и используйте класс col для каждого элемента.<form class="row g-3 align-items-center" method="post" action="{% url 'finances:add-income' %}">
{% csrf_token %}
<div class="col-auto">
<div class="form-floating">
{{ form.amount|add_class:"form-control" }}
<label for="{{ form.amount.id_for_label }}">Сумма</label>
</div>
</div>
<div class="col-auto">
<div class="form-floating">
{{ form.date_bank|add_class:"form-control" }}
<label for="{{ form.date_bank.id_for_label }}">Дата</label>
</div>
</div>
<div class="col-auto">
<button class="btn btn-primary h-100" type="submit">Отправить</button>
</div>
</form>
row g-3создает строку с небольшими отступами между колонками.col-autoзаставляет колонку сжиматься под размер ее содержимого.- Примечание: Для
form-floatingвнутри полей обязательно нужны теги<label>, иначе Bootstrap-эффект "плавающего" текста не будет работать корректно.
max-width: 10ch) или стандартную сетку. Символьная единица измерения ch в CSS идеально подходит для ограничения ширины по количеству знаков.<form class="d-flex flex-column gap-3" method="post" action="{% url 'finances:add-income' %}">
{% csrf_token %}
<!-- Контейнер с ограничением ширины в 10 символов -->
<div style="max-width: 10ch;">
<div class="form-floating">
{{ form.amount|add_class:"form-control" }}
<label for="{{ form.amount.id_for_label }}">Сумма</label>
</div>
</div>
<div style="max-width: 10ch;">
<div class="form-floating">
{{ form.date_bank|add_class:"form-control" }}
<label for="{{ form.date_bank.id_for_label }}">Дата</label>
</div>
</div>
<div style="max-width: 10ch;">
<input class="btn btn-primary w-100" type="submit" value="Отправить">
</div>
</form>
d-flex flex-column gap-3выстраивает элементы вертикально с отступами друг от друга.max-width: 10ch;задает максимальную ширину ровно в 10 символов0.w-100у кнопки растягивает её на всю доступную ширину её 10-символьного контейнера, чтобы она была одинаковой ширины с полями.
form-floating)h-100 (высота 100%), а сами колонки col-auto сделайте одинаковыми по высоте с помощью align-items-stretch в строке:<form class="row g-3 align-items-stretch" method="post" action="{% url 'finances:add-income' %}">
{% csrf_token %}
<div class="col-auto">
<div class="form-floating">
{{ form.amount|add_class:"form-control" }}
<label for="{{ form.amount.id_for_label }}">Сумма</label>
</div>
</div>
<div class="col-auto">
<div class="form-floating h-100">
{{ form.date_bank|add_class:"form-control h-100" }}
<label for="{{ form.date_bank.id_for_label }}">Дата</label>
</div>
</div>
<div class="col-auto d-flex align-items-stretch">
<button class="btn btn-primary px-4" type="submit">Отправить</button>
</div>
</form>
form-floating в пользу классического стиляform-floating) часто конфликтуют с нативными календарями (type="date"). Если сделать форму классической, используя стандартные компактные инпуты Bootstrap, все элементы автоматически станут одной базовой высоты:<form class="row g-2 align-items-center" method="post" action="{% url 'finances:add-income' %}">
{% csrf_token %}
<div class="col-auto">
<!-- Вместо плавающего лейбла используем placeholder или обычный label сверху -->
{{ form.amount|add_class:"form-control" }}
</div>
<div class="col-auto">
{{ form.date_bank|add_class:"form-control" }}
</div>
<div class="col-auto">
<button class="btn btn-primary" type="submit">Отправить</button>
</div>
</form>
Виджет AdminDateWidget тянет за собой скрытые встроенные стили и JavaScript из панели администратора Django. Из-за этого он принудительно добавляет ссылки рядом с инпутом («Today» и иконку календаря), которые ломают выравнивание строки (flex-line) в Bootstrap.
from django import forms
class ReceiptForm(forms.Form):
amount = forms.DecimalField(
label="Сумма",
initial=110050
)
date_bank = forms.DateField(
label="Дата",
widget=forms.DateInput(
attrs={
'type': 'date', # Включает встроенный календарь браузера
'class': 'form-control',
}
)
)
form-floating, для идеального выравнивания по центру строки используйте класс align-items-center на контейнере row.<form class="row g-2 align-items-center" method="post" action="{% url 'finances:add-income' %}">
{% csrf_token %}
<!-- Колонка для суммы -->
<div class="col-auto">
{{ form.amount|add_class:"form-control" }}
</div>
<!-- Колонка для даты -->
<div class="col-auto">
{{ form.date_bank }}
</div>
<!-- Колонка для кнопки -->
<div class="col-auto">
<button class="btn btn-primary" type="submit">Отправить</button>
</div>
</form>
- Исчезнут текстовая ссылка "Today" и иконка, которые смещали инпут даты вниз.
- Поля станут одинаковой высоты и встанут строго по одной горизонтальной оси.
- При клике на поле даты будет открываться аккуратный системный календарь.
Убрать стрелки переключения (spin buttons) у числового поля amount проще всего с помощью короткого CSS-правила. По умолчанию браузеры добавляют эти стрелки для всех инпутов с типом number.
<style>
/* Для Chrome, Safari, Edge и Opera */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Для Firefox */
input[type=number] {
-moz-appearance: textfield;
}
</style>
- Этот код находит все числовые поля на странице и полностью скрывает внутренние элементы управления браузера.
- Поле сохранит все свойства
DecimalField(ввод только цифр и точек/запятых), но визуально станет выглядеть как чистое текстовое поле.
Чтобы кнопка POST-формы визуально ничем не отличалась от обычной GET-ссылки, ей нужно задать класс btn-link и убрать стандартные внутренние отступы с помощью p-0.
<li>
<form method="post" action="{% url 'finances:debug-clear' %}" class="d-inline">
{% csrf_token %}
<button type="submit" class="btn btn-link nav-link p-0 border-0 align-baseline">Инициализировать</button>
</form>
</li>
<li>
<a href="{% url 'finances:debug-state' %}" class="nav-link"><Все таблицы></a>
</li>
btn-link— превращает кнопку в текстовую ссылку.nav-link— добавляет те же стили (цвет, шрифт, поведение), что и у вашей соседней GET-ссылки.p-0 border-0— полностью убирает рамки и внутренние отступы кнопки, которые могли бы её сдвинуть.d-inlineна форме иalign-baselineна кнопке — гарантируют, что скрытый тег<form>не создаст перенос строки и кнопка встанет ровно по базовой линии текста.