0

I have a contact form that I'm trying to use in one of my Django templates. I created a class for it in 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)

and added it to my 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, '[email protected]', ['[email protected]']) 
            except BadHeaderError:
                return HttpResponse('Invalid header found.')
            return redirect ("BobbleHead:home")
      
    form = ContactForm()
    return render(request, "BobbleHead/contact.html", {'form':form})

and am now trying to get the form to render with specific html formatting in my template (contact.html), but am having difficulties.

Previously, I was using the built in Django capabilities to render, like this:

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

That worked fine, but I don't like the way it looks on my webpage and wanted to clean up the formatting. I want the form to render with specific formatting, like this:

<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>

But I'm not sure how to change the <input> elements in the stylized block to use my django form.

2
  • In your html you are can specific fields of your forms(that you created in forms.py) like this : {{form.name}} , so you can use your own containers to style and just call in the input field from the form, if this is what you are looking for... Commented Jun 8, 2022 at 17:48
  • alternatively you can do some designing with crispy forms, here is the doc : django-crispy-forms.readthedocs.io/en/latest Commented Jun 8, 2022 at 17:50

4 Answers 4

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

    )
<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>
Sign up to request clarification or add additional context in comments.

3 Comments

EmailField default widget is EmailInput not TextInput and type and name attribute is by default added, and it will be better if you set max_length as directly inside the field rather than creating as attributes in attrs in widget.
Also by default every field is required see here in docs.
In the question, you will see that she used text for all the inputs, (I know I should use email for EmailField ! As for the second point, you're right! ;) I update my answer!
0

You can add attributes (class, name, etc) to django forms using widgets

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

and in the template refer directly to the fields using {{form.name}}, {{form.comment}} etc to put them anywhere in the template

Comments

0

You can use form attributes, and define error_messages while defining the form and use in the template in the following way.

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
    )

Template file:

<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>

The views.py can be remain same, you can also specify other attributes like help_texts etc.

See all form fields of django.

Comments

0

If you want more granular control over the form rendering (such as changing the size of the input area or keeping previous values in the field when updating a form) do checkout this link: https://www.webforefront.com/django/formtemplatelayout.html

The template looks like this:

<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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.