June 2022 Update on the answer by martinpaulucci and Pepijn:
For Bootstrap 5 and django-crispy-forms 1.14.0, css_class = "form-row" no longer works. Instead use 'row':
class Row(Div):
css_class = 'row'
Here's an example implementation using the Row class defined by Pepijn above (forms.py):
class Row(Div):
css_class = 'row g-3'
class BlogUserCreationForm(UserCreationForm):
"""
Create a custom user creation form using the custom BlogUser user model.
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.layout = Layout(
Row(
Field('username', wrapper_class='form-group col-md-6 mb-0'),
Field('email', wrapper_class='form-group col-md-6 mb-0'),
),
'password1',
'password2',
Row(
Field('first_name', wrapper_class='form-group col-md-4 mb-0'),
Field('last_name', wrapper_class='form-group col-md-4 mb-0'),
Field('date_born', wrapper_class='form-group col-md-4 mb-0'),
),
'short_bio',
Submit('submit', 'Submit')
)
class Meta:
model = BlogUser
fields = ("username", 'email', 'password1', 'password2', 'first_name', 'last_name', 'date_born', 'short_bio')
(I added 'g-3' to my css_class in the implementation to add gutters between the rows).
In case anyone is curious, in my settings.py the crispy_template_pack is still defined as bootstrap4 as per the docs; however, bootstrap5 still seems to work with django-crispy-forms so far as I've found.
CRISPY_TEMPLATE_PACK = 'bootstrap4'