These docs are a work-in-progress and are currently undergoing a major rewrite!

Quickstart forms

Rendering custom forms is not always as straightforward as we wish. Especially if you are looking for custom layouts or designs. But there are a few things we can do to make it easier to do the basics and style the forms using Tailwind CSS.

Default form templates

For standard forms, Forge includes two customized templates.

This allows you to output a vertical, Tailwind-styled form by using {{ form }}:

<form>
    {% csrf_token %}
    {{ form }}

    <button type="submit" class="block w-full px-4 py-2 mt-8 text-white bg-orange-500 rounded-md hover:bg-orange-600">Continue</button>
</form>

The Forge login form is an example of the default styles:

Django login form using Tailwind CSS

Manually rendering fields

When it comes to rendering form fields yourself, our suggestion is to use django-widget-tweaks to make customizations while still letting Django handle the basics. This library is installed by default.

With Tailwind, rendering a field typically means adding classes:

{% load widget_tweaks %}

<form>
    {% csrf_token %}

    {{ form.name|add_class:"block w-full border border-red-600 rounded-md shadow-sm text-sm" }}

    <button type="submit" class="block w-full px-4 py-2 mt-8 text-white bg-orange-500 rounded-md hover:bg-orange-600">Continue</button>
</form>

Once you start rending the fields yourself, you will also be responsible for the labels, errors, and help text:

{% load widget_tweaks %}

<form>
    {% csrf_token %}

    <label for="{{ form.name.id_for_label }}" class="block text-sm font-medium text-gray-700">{{ form.name.label }}</label>

    {{ form.name|add_class:"block w-full border border-red-600 rounded-md shadow-sm text-sm" }}

    {% if errors %}
    <div class="mt-2 text-sm text-red-600">
        {{ errors }}
    </div>
    {% endif %}

    {% if form.name.help_text %}
    <div class="mt-2 text-sm text-gray-600">
        {{ form.name.help_text|safe }}
    </div>
    {% endif %}
</form>

If you find yourself repeating patterns across your app, you can create includable templates to render a field in a specific style:

<form>
    {% csrf_token %}
    {% include "forms/inline_field.html" with field=form.name %}
</form>