Field rendering without violating DRY

I’m laying out a complex form. The fields are arranged in a complex css grid, and the field labels are inline. This requires custom css as well as bootstrap, and for the fields to be rendered individually.

I required each field to be like this:

<div class="row">
    <label for="{{ form.field_one.label }}" class="form-field-label">{{ form.field_one.label }}</label>
    <div class="col-form-input">
        <input type="number" class="form-control form-control-sm" id="{{ form.field_one.auto_id }}" value="{{ form.field_one.value}}">

With 20-odd fields this is a lot of boiler plate code, and the template is a monster. This also violates DRY.

crispy forms has the ability to do render individual fields:

{{ form.field_one|as_crispy_field }}

But this returns html that doesn’t suit my needs.

Is there a way I can define a similar template tag to this crispy one, but specifically define a custom field-template.html so that it spits out my specific field html as shown above? I’ve been trying this in vain all day!

I would appreciate any help!

Actually, you can post your html text - it just needs to be enclosed between lines consisting of three backtick - ` characters. This means you would have a line of ```, then your html, then another line of ```

The line above this is ```
<div><span>this is some text</span></div>
The line after this is ```

Haha I knew there must be a way! Thanks Ken!

updated it now

You can specify a custom template for the rendering of the widgets used by your fields. Look at the templates supplied for the standard widgets, and use them as a guide for creating your own custom rendering templates.

See Built-in Widgets for a list of the templates being used.

(Note: If you want to make your custom templates the defaults across all instances of a widget, you might be able to just recreate the directory structure in your app’s template directory and have Django’s normal search process find your template instead of the default for those widgets. However, I’ve never done this with widgets, so I don’t know if it would work on that level.)

I messed around with trying this for hours and didn’t get there!

The issue I ran into was that the widget html files such as the input.html etc are then combined with the labels in _html_output in BaseForm. and so I ended up rendering what I was looking for but with the unwanted addition of an extra label element above it

I was hoping someone would be able to point me to a tutorial or blog… but maybe it’s one of those things I just need to spend more time on. I’m surprised there aren’t more tutorials out there on this though because it would be really handy

Thanks for the reply Ken. I’ll read through the built in widgets you shared

You can still render the form fields manually, and set the Form’s auto_id attribute to False.

There may be tutorials or blogs out there covering stuff like this, I just don’t have any I can refer you to.

Thanks ken,

rendering manually is what I’m doing already … it just seems to me that it’s a lot of boilerplate to copy/paste with only the field name being unique.

For example, taking the manual fields docs that you just shared:

<div class="fieldWrapper">
    {{ form.subject.errors }}
    <label for="{{ form.subject.id_for_label }}">Email subject:</label>
    {{ form.subject }}
<div class="fieldWrapper">
    {{ form.message.errors }}
    <label for="{{ form.message.id_for_label }}">Your message:</label>
    {{ form.message }}

I was hoping there was a shortcut to achieving the above by just having:

{{ form.subject }}
{{ form.message }}

And having a template that formats these shorthands into the required html

That’s where the custom Widgets / Templates come into play. If the templates being used by your widgets are of your standard format, then you should be able to use your shorthand notation.