Bootstrap4 и формы в Django

Блог Полезное

Bootstrap4 и формы в Django

Bootstrap4 и формы в Django

Есть очень хорошее приложения для отображения форм Django и называется оно django-crispy-forms, именно его и мы и используем в своих сайтах. Удобное, простое и быстрое в освоении, плюс хорошая документация разработчика. 

Используя это приложения не значит быть привязанным именно к Bootsptrap4, можно использовать и более раннии версии bootstrap.

Установка 

pip install django-crispy-forms

Добавьте в INSTALED_APP:


INSTALLED_APPS = [
...

'crispy_forms',
]

CRISPY_TEMPLATE_PACK = 'bootstrap4'

Теперь необходимо подключить bootstrap, либо скачав его и залив на сервер, либо просто воспользоваться ссылками:

Base.html


<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>

В вашем шаблоне должно быть нечто похожее:


<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<title>Django Bootstrap forms</title>
</head>
<body>
<div class="container">
<div class="row justify-content-center">
<div class="col-8">
<h1 class="mt-2">Django Bootstrap forms</h1>
<hr class="mt-0 mb-4">
{% block content %}
{% endblock %}
</div>
</div>
</div>
</body>
</html>

В примере только файл css, но вы можете добавить javascript файл, если он нужен вам.

Создаем модель, например, Company.

Models.py


from django.db import models

class Company(models.Model):
name = models.CharField(max_length=150)
email = models.EmailField(blank=True)
job_title = models.CharField(max_length=50, blank=True)
bio = models.TextField(blank=True)

Допустим мы хотим страницу добавления модели Company. Для этого в файле views.py пропишем:

Views.py


from django.views.generic import CreateView
from .models import Company

class CompanyCreateView(CreateView):
model = Company
fields = ('name', 'email', 'job_title', 'bio')

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

Company_form.html


{% extends 'base.html' %}

{% block content %}
<form method="post">
{% csrf_token %}
{{ form }}
<button type="submit" class="btn btn-success">Save</button>
</form>
{% endblock %}

Это самый обычный вывод формы в django. Теперь, если мы откроем страницу с формой, то увидим такую унылую картинку.

bootstrap form in django

Чтобы рендить форму в Django с помощью bootstrap4 нужно в company_form.html написать так:


{% extends 'base.html' %}

{% load crispy_forms_tags %}

{% block content %}
<form method="post" novalidate>
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-success">Save</button>
</form>
{% endblock %}

И результат, как видите уже гораздо лучше.

django формы

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


{% extends 'base.html' %}

{% load crispy_forms_tags %}

**people/person_form.html**

{% block content %}
<form method="post" novalidate>
{% csrf_token %}
<div class="row">
<div class="col-6">
{{ form.name|as_crispy_field }}
</div>
<div class="col-6">
{{ form.email|as_crispy_field }}
</div>
</div>
{{ form.job_title|as_crispy_field }}
{{ form.bio|as_crispy_field }}
<button type="submit" class="btn btn-success">Save</button>
</form>
{% endblock %}

В результате вы получите что то вроде этого.

crispy-forms

Form Helpers

В django-crispy-forms есть встроенный механизм, который упростит вам разработку, это я вам точно говорю. Покажу пример использования форм, если вам необходимо вывести их с помощью ModelForm.

forms.py


from django import forms
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
from people.models import Company

class CompanyForm(forms.ModelForm):
class Meta:
model = Company
fields = ('name', 'email', 'job_title', 'bio')

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_method = 'post'
self.helper.add_input(Submit('submit', 'Save'))

Обратите внимание, если не добавить add_input, то кнопки в форме не будет. Это очень кратко и просто я описал возможности django-crispy-forms. Если такие классные вещи, как self.helper.layout, в них можно разделить поля на группы и задать каждой группе заголовок, так же прописать каждому полю свой стиль, свой id  и т.д. Вот небольшой пример из моего крайнего проекта:




def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.layout = Layout(
Fieldset(
'Откуда',
'country_from',
'city_from',
'railway_from',
),
Fieldset(
'Куда',
'country_to',
'city_to',
'railway_to',
),
Fieldset(
'Остальные данные',
'view_of_cargo',
'type_of_container',
'type_of_vagon',
'date',
'cargo_capacity',
'height',
'width',
'length',
'amount',
'no_gabarite',
),
ButtonHolder(
Submit('submit', _('Add'), css_class='form_button')
)
)
self.fields['country_from'].widget.attrs.update({'class' : 'custom-select'})
self.fields['country_from'].label = 'Страна откуда'

Эксперементируйте и пользуйтесь этим приложением, с его помощью можно вывести любую форму и на любой вкус.