Django Forms provides basic data input functionality, but styling forms is crucial for enhancing user experience. In this article, we will explore how to style Django Forms using CSS and real-world examples.


1. Basic HTML Forms and Django Forms

1.1 Basic Output Methods of Django Forms

Django Forms automatically generate HTML by default. The basic output methods are as follows:

  • as_p: Wraps each field in a <p> tag.
  • as_table: Renders each field in a <tr> tag.
  • as_ul: Wraps each field in a <li> tag.

Example: Basic Output Method

class ExampleForm(forms.Form):
    name = forms.CharField(label="Your Name")
    email = forms.EmailField(label="Your Email")
<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Submit</button>
</form>

The above code will be displayed in the default style wrapped in <p> tags.


2. Styling Forms with CSS

A visually engaging webpage mockup displaying a stylish Django form integrated with CSS and Bootstrap

2.1 Applying Styles with the attrs Attribute and Bootstrap

The attrs attribute allows you to directly add CSS classes to HTML tags. This makes it easy to apply CSS frameworks like Bootstrap.

Example: Applying Bootstrap Styles with attrs

class BootstrapForm(forms.Form):
    username = forms.CharField(
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': 'Enter your username'
        })
    )
    password = forms.CharField(
        widget=forms.PasswordInput(attrs={
            'class': 'form-control',
            'placeholder': 'Enter your password'
        })
    )

Rendering the Form in a Template

<form method="post">
    {% csrf_token %}
    <div class="form-group">
        <label for="id_username">Username</label>
        {{ form.username }}
    </div>
    <div class="form-group">
        <label for="id_password">Password</label>
        {{ form.password }}
    </div>
    <button type="submit" class="btn btn-primary">Submit</button>
</form>

Example Result HTML

<input type="text" name="username" class="form-control" placeholder="Enter your username">
<input type="password" name="password" class="form-control" placeholder="Enter your password">

2.2 Form Styling Using Bootstrap

Example: Applying Bootstrap Styles

class BootstrapForm(forms.Form):
    username = forms.CharField(
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': 'Enter your username'
        })
    )
    password = forms.CharField(
        widget=forms.PasswordInput(attrs={
            'class': 'form-control',
            'placeholder': 'Enter your password'
        })
    )

Rendering the Form in a Template

<form method="post">
    {% csrf_token %}
    <div class="form-group">
        <label for="id_username">Username</label>
        {{ form.username }}
    </div>
    <div class="form-group">
        <label for="id_password">Password</label>
        {{ form.password }}
    </div>
    <button type="submit" class="btn btn-primary">Submit</button>
</form>

Result Display

  • The form fields and buttons styled with Bootstrap will be rendered.

3. Using Django FormHelper and Libraries

3.1 Introduction to django-crispy-forms

django-crispy-forms offers better styling and layout management for Django Forms.

Installation

pip install django-crispy-forms

Configuration

Add the following to settings.py:

INSTALLED_APPS += [
    'crispy_forms',
]
CRISPY_ALLOWED_TEMPLATE_PACKS = ["bootstrap5"]
CRISPY_TEMPLATE_PACK = 'bootstrap5'

Defining the Form

from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit

class CrispyForm(forms.Form):
    email = forms.EmailField(label="Your Email")

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

Considerations

django-crispy-forms is useful for simple form styling, but if the __init__ method is not properly configured, it can lead to an excessive number of debug logs. If you want to keep your log files tidy, be mindful of this point. It's recommended for developers working with debug logging off or those who do not mind messy logs, but personally, I do not prefer this styling method. To prevent debug log generation, you need to configure the initialization method perfectly, which often requires digging into the source code for analysis. At that point, I would rather style it another way.

Using in Templates

<form method="post">
    {% csrf_token %}
    {{ form|crispy }}
</form>

4. Real-World Case: Styling a Signup Form

4.1 Defining the Form

class SignupForm(forms.Form):
    username = forms.CharField(
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': 'Enter your username'
        })
    )
    email = forms.EmailField(
        widget=forms.EmailInput(attrs={
            'class': 'form-control',
            'placeholder': 'Enter your email'
        })
    )
    password = forms.CharField(
        widget=forms.PasswordInput(attrs={
            'class': 'form-control',
            'placeholder': 'Enter your password'
        })
    )

4.2 Rendering in a Template

<form method="post">
    {% csrf_token %}
    <div class="form-group">
        <label for="id_username">Username</label>
        {{ form.username }}
    </div>
    <div class="form-group">
        <label for="id_email">Email</label>
        {{ form.email }}
    </div>
    <div class="form-group">
        <label for="id_password">Password</label>
        {{ form.password }}
    </div>
    <button type="submit" class="btn btn-success">Sign Up</button>
</form>

5. Conclusion

By leveraging Django Forms and CSS, you can significantly enhance user experience. Try out various methods, from basic styling using attrs to advanced styling with libraries like Bootstrap and django-crispy-forms. And remember, when using django-crispy-forms, pay attention to the initialization method __init__ to keep your log files clean!

In the next article, we will discuss Advanced Usage of Django Forms.