Форматирование элементов форм Django в html-шаблонах

У меня есть контактная форма, которую я пытаюсь использовать в одном из моих шаблонов Django. Я создал класс для нее в файле forms.py:

class ContactForm(forms.Form):
name = forms.CharField(max_length=100)
email_address = forms.EmailField(max_length=150)
message = forms.CharField(widget = forms.Textarea,max_length=2000)

и добавил его в мой views.py:

def contact(request):
if request.method == 'POST':
    form = ContactForm(request.POST)
    if form.is_valid():
        subject = "Website Inquiry" 
        body = {
        'name': form.cleaned_data['name'], 
        'email': form.cleaned_data['email_address'], 
        'message':form.cleaned_data['message'], 
        }
        message = "\n".join(body.values())

        try:
            send_mail(subject, message, 'admin@example.com', ['admin@example.com']) 
        except BadHeaderError:
            return HttpResponse('Invalid header found.')
        return redirect ("BobbleHead:home")
  
form = ContactForm()
return render(request, "BobbleHead/contact.html", {'form':form})

и сейчас пытаюсь заставить форму отображаться с определенным html-форматированием в моем шаблоне (contact.html), но испытываю трудности.

Ранее я использовал встроенные возможности Django для рендеринга, например, так:

<form action="" method="post">
   {% csrf_token %}
     {{ form.as_p }}
     <button type="submit">Submit</button>
</form>

Это сработало отлично, но мне не нравится, как это выглядит на моей веб-странице, и я хотел бы очистить форматирование. Я хочу, чтобы форма отображалась с определенным форматированием, например, так:

<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<div class="w3-col m6">
    <form action="/home" target="_blank">
      {% csrf_token %}
      <div class="w3-row-padding" style="margin:0 -16px 8px -16px">
        <div class="w3-half">
          <div class="fieldWrapper">
          <input class="w3-input w3-border" type="text" placeholder="Name" required name="name">
          </div>
        </div>
        <div class="w3-half">
          <input class="w3-input w3-border" type="text" placeholder="Email" required name="email_address">
        </div>
      </div>
      <input class="w3-input w3-border" type="text" placeholder="Message" required name="message">
      <button class="w3-button w3-black w3-section w3-right" type="submit">SEND</button>
    </form>
  </div>

Но я не уверен, как изменить элементы <input> в стилизованном блоке, чтобы использовать мои django form.

Вы можете добавлять атрибуты (класс, имя и т.д.) к формам django с помощью виджетов

class CommentForm(forms.Form):
    name = forms.CharField(widget=forms.TextInput(attrs={'class': 'special'}))
    url = forms.URLField()
    comment = forms.CharField(widget=forms.TextInput(attrs={'size': '40'}))

https://docs.djangoproject.com/en/4.0/ref/forms/widgets/#styling-widget-instances

и в шаблоне ссылайтесь непосредственно на поля, используя {{form.name}}, {{form.comment}} и т.д., чтобы разместить их в любом месте шаблона

class ContactForm(forms.Form):
    name = forms.CharField(
        widget=forms.TextInput(
            attrs={
                "class": "w3-input w3-border",
                "type": "text",
                "placeholder": "Name",
                "required": "required",
                "max_length": "100",
                "name": "name",
            }
        )
    )
    email_address = forms.EmailField(
        widget=forms.TextInput(
            attrs={
                "class": "w3-input w3-border",
                "type": "text",
                "placeholder": "Email",
                "required": "required",
                "max_length": "150",
                "name": "email_address",
            }
        )
    )
    message = forms.CharField(
        widget=forms.TextInput(
            attrs={
                "class": "w3-input w3-border",
                "type": "text",
                "placeholder": "Message",
                "required": "required",
                "max_length":"2000",
                "name": "message",
            }
        )
    )

<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<div class="w3-col m6">
  <form action="" method="post">
    {% csrf_token %}
    <div class="w3-row-padding" style="margin:0 -16px 8px -16px">
      <div class="w3-half">
        {{ form.name }}
      </div>
      <div class="w3-half">
        {{ form.email_address }}
      </div>
    </div>
    {{  form.message }} 
    <button class="w3-button w3-black w3-section w3-right" type="submit">SEND</button>
  </form>
</div>

Вы можете использовать атрибуты формы и определять сообщения об ошибках при определении формы и использовании в шаблоне следующим образом.

forms.py

class ContactForm(forms.Form):
    name = forms.CharField(
        widget=forms.TextInput(
            attrs={
                "class": "w3-input w3-border",
                "placeholder": "Name"
            }
        ),
        error_messages={
         'required':'name is required'
        },
        max_length=100
    )
    email_address = forms.EmailField(
        widget=forms.EmailInput(
            attrs={
                "class": "w3-input w3-border",
                "placeholder": "Email",
            }
        ),
        error_messages={
        "required":"Email is required"
        },
        max_length=150
    )
    message = forms.CharField(
        widget=forms.TextInput(
            attrs={
                "class": "w3-input w3-border",
                "placeholder": "Message",
            }
        ),
        error_messages={
        'required':'Message is required'
        },
        max_length=2000
    )

Файл шаблона:

<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<div class="w3-col m6">
    <form action="/home" target="_blank">
      {% csrf_token %}
      <div class="w3-row-padding" style="margin:0 -16px 8px -16px">
        <div class="w3-half">
          <div class="fieldWrapper">
          {{form.name}}
          {% for error in form.name.errors %}
             {{error|striptags}}
          {% endfor %}
          </div>
        </div>
        <div class="w3-half">
          {{form.email}}
          {% for error in form.email.errors %}
            {{error|striptags}}
          {% endfor %}

        </div>
      </div>
      {{form.message}}
      {% for error in form.message.errors %}
      {{error|striptags}}
      {% endfor %}
      
      <button class="w3-button w3-black w3-section w3-right" type="submit">SEND</button>
    </form>
  </div>

views.py может оставаться таким же, вы также можете указать другие атрибуты, такие как help_texts и т.д.

Посмотреть все form fields из django.

Если вам нужен более детальный контроль над рендерингом формы (например, изменение размера области ввода или сохранение предыдущих значений в поле при обновлении формы), обратитесь к этой ссылке: https://www.webforefront.com/django/formtemplatelayout.html

Шаблон выглядит следующим образом:

<form method="POST" enctype="multipart/form-data">
  {% csrf_token %}
  {{ form.non_field_errors }}

  <div class="fieldWrapper">
    <h5>Field1</h5>
    {{ form.Field1.errors }}  // To render any error messages
    {{ form.Field1 }}  // If you want the form field as default
  </div>
  
  <div class="fieldWrapper">
    <h5>Field2</h5>
    {{ form.Field2.errors }}  
    <input value="{{ <model.field> }}" type="text" name="Field2" size="10">  // If you want to be able to change the size or would like to keep the last updated value in the text field (where name="<your_form_field_name>") 
  </div>

<button type="submit">Update</button>
</form>
Вернуться на верх