I'm rewriting my website with Django, and I would like to utilize Django forms since it's really easier than writing every form by hand in HTML. I looked at crispy-forms documentation and found out there is something called Layout. I don't know if I'm using as intended or if I'm repeating myself over and over, but here is what I got:
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 %}
As you can see length of the input boxes are not same, which is not okay. It's like every row doesn't use full the width. How can I make them use the same width?
Also I would appreciate other suggestions, like easier way of doing this whole form. Maybe utilizing Row is a better idea in my case?

Yes, you are using layout correctly. My preference is not to clutter up the form's
__init__with lots of lines, but rather to place the layout in a function in the same file as the form, and do this. It's purely code-stylistic.CSS styling of
<input>and<select>elements is a right pain, but this is what you need. Crispy will let you add classes to specify the elements. Your<input>s are one width (default?), your<select>s are different.I find the Firefox browser very helpful for experimenting. You can right-click and "inspect", then add or remove CSS attributes(?) until you arrive at what works. Then add it to your style sheet.
An example of mine (for a Crispy MultiField with css_class="multi-wide"...)
You may need
!important, or high specificity, in order to "win" if bootstrap or some other framework is trying to control these elements for you. Firefox will show you where the current settings of the element are coming from.