Skip to main content

Crispy Forms GDS

A GOV.UK Design System template pack for Django Crispy Forms, for simple and powerful form generation which is compliant with GDS usability and accessibility guidelines.

https://codecov.io/gh/wildfish/crispy-forms-gds/branch/master/graph/badge.svg https://badge.fury.io/py/crispy-forms-gds.svg https://img.shields.io/pypi/pyversions/crispy-forms-gds.svg

Compatibility

crispy-forms-gds

Government Design System

django-crispy-forms

django

0.x

3.5

1.x - 2.2

3.2 LTS, 4.2 LTS

1.x

5.0 - 5.2

2.0 - 2.3

4.2 LTS

2.x

5.0 - 5.8

2.0 - 2.3

5.0, 5.1

Both Version 1.x and 2.x are still in development.

The Government Design System versions will be updated as each release is tested.

There are components which have not yet been implemented. Check the issues for details.

Quickstart

This is a minimal howto without options or details - see the crispy-forms-gds documentation for full instructions for installation and usage.

Install using pip:

pip install crispy-forms-gds

Add to installed apps, with settings to tell django-crispy-forms to use this theme, along with the version number of the govuk frontend you are using:

INSTALLED_APPS = [
  ...
  'crispy_forms',
  'crispy_forms_gds',
]
CRISPY_ALLOWED_TEMPLATE_PACKS = ["gds"]
CRISPY_TEMPLATE_PACK = "gds"
CRISPY_GDS_FRONTEND_VERSION = "5.0.0"

Build a regular crispy form using layout objects from crispy_forms_gds:

from django import forms

from crispy_forms_gds.helper import FormHelper
from crispy_forms_gds.layout import Submit


class SimpleForm(forms.Form):

    name = forms.CharField(
        label="Name",
        help_text="Your full name.",
        widget=forms.TextInput(),
        error_messages={
            "required": "Enter your name as it appears on your passport"
        }
    )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.add_input(Submit("submit", "Submit"))

Render the form in your templates as normal:

{% load crispy_forms_tags %}
{% crispy form %}

Examples

The template pack supports all the basic components listed in the GOV.UK Design System. Here are some examples taken from the demo site included in the project.

Accordion

Layout components, such as the Accordion let you generate complex forms with multiple sections:

from django import forms

from crispy_forms_gds.helper import FormHelper
from crispy_forms_gds.layout import HTML, Accordion, AccordionSection, Layout


class AccordionForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.layout = Layout(
            Accordion(
                AccordionSection(
                    "Writing well for the web",
                    HTML.p("This is the content for Writing well for the web."),
                    summary="An introduction to clear and concise writing.",
                ),
                AccordionSection(
                    "Writing well for specialists",
                    HTML.p("This is the content for Writing well for specialists."),
                ),
                AccordionSection(
                    "Know your audience",
                    HTML.p("This is the content for Know your audience."),
                ),
                AccordionSection(
                    "How people read",
                    HTML.p("This is the content for How people read."),
                ),
            )
        )
docs/screenshots/accordion.png

Radio Buttons

ChoiceFields can be displayed as Select or Radio components. Radio buttons also support Design System features such as sizing, hinting and dividers:

from django import forms

from crispy_forms_gds.choices import Choice
from crispy_forms_gds.helper import FormHelper
from crispy_forms_gds.layout import Button, Field, Layout, Size


class RadiosForm(forms.Form):

    name = forms.ChoiceField(
        choices=(("yes", "Yes"), ("no", "No")),
        widget=forms.RadioSelect,
        label="Have you changed your name?",
        help_text="This includes changing your last name or spelling your name differently.",
        error_messages={"required": "Enter whether your name has changed"},
    )

    METHODS = (
        Choice("email", "Email", hint="Do not use an email address from work"),
        Choice("phone", "Phone", divider="Or"),
        Choice("text", "Text message"),
    )

    method = forms.ChoiceField(
        choices=METHODS,
        widget=forms.RadioSelect,
        label="How would you like to be contacted?",
        help_text="Select the options that is best for you.",
        error_messages={
            "required": "Select the best way to send a confirmation message"
        },
    )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.layout = Layout(
            Field.radios("name", legend_size=Size.MEDIUM, legend_tag="h1", inline=True),
            Field.radios("method", legend_size=Size.MEDIUM, small=True),
            Button("submit", "Submit"),
        )
docs/screenshots/radio-buttons.png

Validation Errors

Forms fully support the Error Message and Error Summary components with no extra effort on your part:

from django import forms

from crispy_forms_gds.helper import FormHelper
from crispy_forms_gds.layout import (
    Button,
    Field,
    Fieldset,
    Fixed,
    Fluid,
    Layout,
    Size,
)


class UserForm(forms.Form):

    name = forms.CharField(
        label="Your name",
        help_text="Enter your name as it appears on your passport.",
    )

    email = forms.CharField(
        label="Email",
        help_text="Enter your email address.",
        widget=forms.EmailInput,
    )

    phone = forms.CharField(
        label="Phone",
        help_text="Enter your home or mobile telephone number.",
    )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.label_size = Size.SMALL
        self.helper.layout = Layout(
            Fieldset(
                Field.text("name"),
                Field.text("email", field_width=Fluid.TWO_THIRDS),
                Field.text("phone", field_width=Fixed.TEN),
            ),
            Button("submit", "Submit"),
        )
docs/screenshots/validation-errors.png

Demo

If you checkout the code from the repository, there is a Django site you can run to see the forms in action:

git clone git@github.com:wildfish/crispy-forms-gds.git
cd crispy-forms-gds

First, create a virtual environment:

uv venv

Activate it:

source .venv/bin/activate

Install all the dependencies:

uv sync

Next, copy and install the precompiled govuk-frontend files in the assets directory in the project root:

1. Download the pre-compiled files provided at bottom of each GOV.UK Frontend release note. 2. Unzip the zip file. 3. Copy the files in assets/fonts to assets/fonts. 4. Copy the files in assets/images to assets/images. 5. Copy the file, assets/manifest.json to assets. 6. Copy the .css and .css.map files to assets/stylesheets. 7. Copy the .js and .js.map files to assets/javascripts. 8. Edit demo/settings.py to set GDS_VERSION to the version you downloaded.

Create a copy of the .env.example file and edit it to set the version number of the govuk-frontend you downloaded:

cp .env.example .env

Now, setup and run Django:

python manage.py migrate
python manage.py runserver

Open http://localhost:8000/ in your browser to see forms built with Django Crispy Forms styled using the GOV.UK Design System.

Project Information

The app is tested with Python 3.10+, and version 1.x officially supports Django 4.2 LTS, and Django Crispy Forms 2.x. Version 2.x supports Django 5.0, 5.1, and Django Crispy Forms 2.x. The app simply generates HTML, so it can probably be used with earlier versions of Django and Django Crispy Forms.

Crispy Forms GDS is released under the terms of the MIT license.

Metadata

Release files for crispy-forms-gds 2.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for crispy-forms-gds 2.0.1
File Size Uploaded
crispy_forms_gds-2.0.1.tar.gz 36.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for crispy-forms-gds 2.0.1
File Interpreter ABI Platform
crispy_forms_gds-2.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 81.0 kB

Release files / crispy_forms_gds-2.0.1.tar.gz

Download URL crispy_forms_gds-2.0.1.tar.gz
Size 36.9 kB
Tags Source
SHA-256 checksum
How to use checksums
703a91474206684f286c27351bd504f22605b346ce4e5e54af33873f27ca316d
BLAKE2b-256 checksum
How to use checksums
fed79aeb6b39098bcb93801344f9e1b10de6e5d5813739a35e12d1b6da0a5001
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.5.17

Release files / crispy_forms_gds-2.0.1-py3-none-any.whl

Download URL crispy_forms_gds-2.0.1-py3-none-any.whl
Size 44.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
485158d5cb4a3a04553d50532b6ba3db0e3dd809d3bda46b30f43b8f9274119f
BLAKE2b-256 checksum
How to use checksums
dea8c3c17cc7f5ad75d03c2808bd99358f0f3b6d997ae05220a2c3ad9e2875e8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.5.17

Release history Release notifications | RSS feed

This release

2.0.1 This release

2 release files

2.0.0

2 release files

1.0.0

2 release files

0.3.2

3 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

3 release files

0.2.0

2 release files

0.1.0

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page