How to insert heading between fields in CBV ModelForm

Hello,

I am new to Django and have built my form using class-based views and the ModelForm.
I’m using django-crispy-forms to render the forms with Bootstrap 5 styling.

If I want to insert a heading (

tags or some other HTML) between two of the fields in the list of form fields, how would I do that?

Here is a reduced example of my forms.py that has a ton of fields:

from django.forms import ModelForm, widgets
from .models import Client

class ClientForm(ModelForm):
	class Meta:
		model = Client
		fields = ('first_name',
				  'last_name',
				  'gender',
				  'date_of_birth',
				  'marital_status',
				  'preferred_language')
		widgets = {
			'date_of_birth': widgets.DateInput(attrs={'type': 'date'})
		}

Here is the edit.html template for the model:

{% extends "base.html" %}
{% block title %}Edit Client{% endblock %}

{% block content %}
    <div class="row">
        <div class="col-sm-12 col-lg-6">
            <h2>{{ client.full_name }}</h2>

            {% load crispy_forms_tags %}
            <form action="" method="POST">
                {% csrf_token %}
                {{ form|crispy }}
                <button class="btn btn-primary">Save</button>
                <a href="{{ view.get_success_url }}" class="btn btn-light">Cancel</a>
            </form>
        </div>
    </div>
{% endblock content %}

And the reduced section of models.py in case you need it:

class Client(TheBaseClass):
    first_name = models.CharField(max_length=50, default='')
    last_name = models.CharField(max_length=50, default='')
    date_of_birth = models.DateField(blank=True, null=True)
    active = models.BooleanField(default=False)
    gender = models.CharField(max_length=20, choices=Gender.choices, blank=True, default='')
    marital_status = models.CharField(max_length=20, choices=MaritalStatus.choices, blank=True, default='')
    preferred_language = models.CharField(max_length=20, choices=PreferredLanguage.choices, blank=True, default=PreferredLanguage.ENGLISH)

    def __str__(self):
        return "%s %s" % (self.first_name, self.last_name)
        # return self.full_name()

    def get_absolute_url(self): # new
        return reverse('clients:detail', args=[str(self.id)])

    def full_name(self):
        return f"{self.first_name} {self.last_name}"

Can you please advise on the best/cleanest approach?

Thanks in advance!

Unfortunately, your sample tag in the text of your post is filtered out by the forum software. When you want to include the text of html in your post, surround the html by single backtick - ` characters - it’ll look like this: <div> This is a div </div>.

Anyway, take a look at the Layout class. That’s what we use to build our form layouts. We find it incredibly useful.

1 Like

Thank you for the response!

The HTML I included before was just a <H3> tag. So, I was just looking for a way to insert HTML in between the form fields.

Thank you for the link to the Layout class for django-crispy-forms. It looks powerful, and I will most likely need to go that route.

Out of curiosity, is there not a more “native” way to do this in the ModelForm in Django? Without using the crispy-forms package?

If not, I’m glad to start constructing the layouts with crispy-forms before I get too far down the road.

Sure - you can render the form field-by-field, you can modify the form template, or you can modify individual widgets if that <h3> is associated with a field.

See Working with form templates

1 Like

You, sir, are a terrific human and your contributions to this site are legendary.
Thank you!