A Django form field represents one submitted input value and describes how that value is rendered and validated. A Form instance groups fields, while each field corresponds to an HTML control. Django keeps the connection between Python and HTML deliberately loose: a form can render the control for you, but the view still decides how submitted data is processed. section 7.1
Each field uses a widget to produce HTML. A CharField normally uses an input element, while a Textarea widget can replace that default. Widgets also cover email inputs, selects, radio buttons, dates, times, and file inputs. Rendering is convenient, but detailed page layout may still require custom templates. section 7.1 section 7.6
A comment form with two fields
from django import forms class CommentForm(forms.Form): name = forms.CharField() comment = forms.CharField( widget=forms.Textarea( attrs={"rows": "6", "cols": "50"} ) ) Here, name renders as a required text input. comment renders as a required textarea with six rows and fifty columns. Calling f.as_p() on a CommentForm instance renders both fields with labels, names, IDs, and required attributes.
A typical view displays an unbound form for GET requests and binds request.POST for POST requests. Calling is_valid() checks the submitted values against the field definitions; when validation succeeds, cleaned_data provides the values under the corresponding field names. section 7.6
class CommentForm(forms.Form):
name = forms.CharField(template_name="custom_input_field.html") #1
...
Django 5 lets a field select a reusable template for its complete field structure, including labels, inputs, help text, and layout. This supports Bootstrap-style markup without abandoning field declarations. section 7.1.4

