{"id":75672,"date":"2020-01-20T11:29:11","date_gmt":"2020-01-20T05:59:11","guid":{"rendered":"https:\/\/www.vskills.in\/certification\/tutorial\/?p=75672"},"modified":"2024-04-12T14:17:14","modified_gmt":"2024-04-12T08:47:14","slug":"processing-the-submission","status":"publish","type":"page","link":"https:\/\/www.vskills.in\/certification\/tutorial\/processing-the-submission\/","title":{"rendered":"Processing the Submission"},"content":{"rendered":"<p>Once the user has filled the form to the point that it passes our validation rules, we need to do something useful with the data. In this case, we want to construct and send an email containing the user\u2019s feedback. We\u2019ll use Django\u2019s email package to do this.<\/p>\n<p>First, though, we need to tell if the data is indeed valid, and if it is, we need access to the validated data. The forms framework does more than just validate the data, it also converts it into Python types. Our contact form only deals with strings, but if we were to use an IntegerField or DateTimeField, the forms framework would ensure that we got back a Python integer or datetime object, respectively. To tell whether a form is bound to valid data, call the is_valid() method:<\/p>\n<p>form = ContactForm(request.POST)<br>\nif form.is_valid():<br>\n# Process form data<\/p>\n<p>Now we need access to the data. We could pull it straight out of request.POST, but if we did, we\u2019d miss out on the type conversions performed by the forms framework. Instead, we use form.clean_data:<\/p>\n<p>if form.is_valid():<br>\ntopic = form.clean_data[&#8216;topic&#8217;]\nmessage = form.clean_data[&#8216;message&#8217;]\nsender = form.clean_data.get(&#8216;sender&#8217;, &#8216;noreply@example.com&#8217;)<br>\n# &#8230;<\/p>\n<p>Note that since sender is not required, we provide a default when it\u2019s missing. Finally, we need to record the user\u2019s feedback. The easiest way to do this is to email it to a site administrator. We can do that using the send_mail function:<\/p>\n<p>from django.core.mail import send_mail<br>\n# &#8230;<br>\nsend_mail(<br>\n&#8216;Feedback from your site, topic: %s&#8217; % topic,<br>\nmessage, sender,<br>\n[&#8216;administrator@example.com&#8217;]\n)<\/p>\n<p>The send_mail function has four required arguments: the email subject, the email body, the \u201cfrom\u201d address, and a list of recipient addresses. send_mail is a convenient wrapper around Django\u2019s EmailMessage class, which provides advanced features such as attachments, multipart emails, and full control over email headers.<\/p>\n<p>Having sent the feedback email, we\u2019ll redirect our user to a static confirmation page. The finished view function looks like this:<\/p>\n<p>from django.http import HttpResponseRedirect<br>\nfrom django.shortcuts import render_to_response<br>\nfrom django.core.mail import send_mail<br>\nfrom forms import ContactForm<\/p>\n<p>def contact(request):<br>\nif request.method == &#8216;POST&#8217;:<br>\nform = ContactForm(request.POST)<br>\nif form.is_valid():<br>\ntopic = form.clean_data[&#8216;topic&#8217;]\nmessage = form.clean_data[&#8216;message&#8217;]\nsender = form.clean_data.get(&#8216;sender&#8217;, &#8216;noreply@example.com&#8217;)<br>\nsend_mail(<br>\n&#8216;Feedback from your site, topic: %s&#8217; % topic,<br>\nmessage, sender,<br>\n[&#8216;administrator@example.com&#8217;]\n)<br>\nreturn HttpResponseRedirect(&#8216;\/contact\/thanks\/&#8217;)<br>\nelse:<br>\nform = ContactForm()<br>\nreturn render_to_response(&#8216;contact.html&#8217;, {&#8216;form&#8217;: form})<\/p>\n<p><strong>Redirect After POST<\/strong> &#8211; If a user selects Refresh on a page that was displayed by a POST request, that request will be repeated. This can often lead to undesired behavior, such as a duplicate record being added to the database. Redirect after POST is a useful pattern that can help avoid this scenario: after a successful POST has been processed, redirect the user to another page rather than returning HTML directly.<\/p>\n<h3>Simple Validation<\/h3>\n<p>Our search example is still reasonably simple, particularly in terms of its data validation; we\u2019re merely checking to make sure the search query isn\u2019t empty. Many HTML forms include a level of validation that\u2019s more complex than making sure the value is non-empty. We\u2019ve all seen the error messages on web sites:=<\/p>\n<ul>\n<li>&nbsp;\u201cPlease enter a valid e-mail address. \u2018foo\u2019 is not an e-mail address.\u201d<\/li>\n<li>\u201cPlease enter a valid five-digit U.S. ZIP code. \u2018123\u2019 is not a ZIP code.\u201d<\/li>\n<li>\u201cPlease enter a valid date in the format YYYY-MM-DD.\u201d<\/li>\n<li>\u201cPlease enter a password that is at least 8 characters long and contains at least one number.\u201d<\/li>\n<\/ul>\n<p>Let\u2019s tweak our search() view so that it validates that the search term is less than or equal to 20 characters long. (For sake of example, let\u2019s say anything longer than that might make the query too slow.) How might we do that? The simplest possible thing would be to embed the logic directly in the view, like this:<\/p>\n<p>def search(request):<br>\nerror = False<br>\nif &#8216;q&#8217; in request.GET:<br>\nq = request.GET[&#8216;q&#8217;]\nif not q:<br>\nerror = True<br>\nelif len(q) &gt; 20:<br>\nerror = True<br>\nelse:<br>\nbooks = Book.objects.filter(title__icontains=q)<br>\nreturn render(request, &#8216;search_results.html&#8217;, {&#8216;books&#8217;: books, &#8216;query&#8217;: q})<br>\nreturn render(request, &#8216;search_form.html&#8217;, {&#8216;error&#8217;: error})<\/p>\n<p>Now, if you try submitting a search query greater than 20 characters long, it won\u2019t let you search; you\u2019ll get an error message. But that error message in search_form.html currently says &#8220;Please submit a search term.&#8221;\u2013 so we\u2019ll have to change it to be accurate for both cases:<\/p>\n<p>&lt;html&gt;<br>\n&lt;head&gt;<br>\n&lt;title&gt;Search&lt;\/title&gt;<br>\n&lt;\/head&gt;<br>\n&lt;body&gt;<br>\n{% if error %}<br>\n&lt;p style=&#8221;color: red;&#8221;&gt;<br>\nPlease submit a search term 20 characters or shorter.<br>\n&lt;\/p&gt;<br>\n{% endif %}<\/p>\n<p>&lt;form action=&#8221;\/search\/&#8221; method=&#8221;get&#8221;&gt;<br>\n&lt;input type=&#8221;text&#8221; name=&#8221;q&#8221;&gt;<br>\n&lt;input type=&#8221;submit&#8221; value=&#8221;Search&#8221;&gt;<br>\n&lt;\/form&gt;<br>\n&lt;\/body&gt;<br>\n&lt;\/html&gt;<\/p>\n<p>There\u2019s something ugly about this. Our one-size-fits-all error message is potentially confusing. Why should the error message for an empty form submission mention anything about a 20-character limit? Error messages should be specific, unambiguous and not confusing. The problem is in the fact that we\u2019re using a simple boolean value for error, whereas we should be using a list of error message strings. Here\u2019s how we might fix that:<\/p>\n<p>def search(request):<br>\nerrors = []\nif &#8216;q&#8217; in request.GET:<br>\nq = request.GET[&#8216;q&#8217;]\nif not q:<br>\nerrors.append(&#8216;Enter a search term.&#8217;)<br>\nelif len(q) &gt; 20:<br>\nerrors.append(&#8216;Please enter at most 20 characters.&#8217;)<br>\nelse:<br>\nbooks = Book.objects.filter(title__icontains=q)<br>\nreturn render(request, &#8216;search_results.html&#8217;, {&#8216;books&#8217;: books, &#8216;query&#8217;: q})<br>\nreturn render(request, &#8216;search_form.html&#8217;, {&#8216;errors&#8217;: errors})<\/p>\n<p>Then, we need make a small tweak to the search_form.html template to reflect that it\u2019s now passed an errors list instead of an error boolean value:<\/p>\n<p>&lt;html&gt;<br>\n&lt;head&gt;<br>\n&lt;title&gt;Search&lt;\/title&gt;<br>\n&lt;\/head&gt;<br>\n&lt;body&gt;<br>\n{% if errors %}<br>\n&lt;ul&gt;<br>\n{% for error in errors %}<br>\n&lt;li&gt;{{ error }}&lt;\/li&gt;<br>\n{% endfor %}<br>\n&lt;\/ul&gt;<br>\n{% endif %}<br>\n&lt;form action=&#8221;\/search\/&#8221; method=&#8221;get&#8221;&gt;<br>\n&lt;input type=&#8221;text&#8221; name=&#8221;q&#8221;&gt;<br>\n&lt;input type=&#8221;submit&#8221; value=&#8221;Search&#8221;&gt;<br>\n&lt;\/form&gt;<br>\n&lt;\/body&gt;<br>\n&lt;\/html&gt;<\/p>\n<h3>Making a Contact Form<\/h3>\n<p>Although we iterated over the book search form example several times and improved it nicely, it\u2019s still fundamentally simple: just a single field, &#8216;q&#8217;. As forms get more complex, we have to repeat the above steps over and over again for each form field we use. This introduces a lot of cruft and a lot of opportunities for human error. Lucky for us, the Django\u2019s developers thought of this and built into Django a higher-level library that handles form- and validation-related tasks.<\/p>\n<p>Your First Form Class &#8211; Django comes with a form library, called django.forms, that handles many of the issues we\u2019ve been exploring this chapter \u2013 from HTML form display to validation. Let\u2019s dive in and rework our contact form application using the Django forms framework. The primary way to use the forms framework is to define a Form class for each HTML &lt;form&gt; you\u2019re dealing with.<\/p>\n<p>In our case, we only have one &lt;form&gt;, so we\u2019ll have one Form class. Django community convention is to keep Form classes in a separate file called forms.py. Create this file in the same directory as your mysite\\views.py, and enter the following:<\/p>\n<p># mysite_project\\mysite\\mysite\\forms.py<\/p>\n<p>from django import forms<\/p>\n<p>class ContactForm(forms.Form):<br>\nsubject = forms.CharField()<br>\nemail = forms.EmailField(required=False)<br>\nmessage = forms.CharField()<\/p>\n<p>This is pretty intuitive, and it\u2019s similar to Django\u2019s model syntax. Each field in the form is represented by a type of Field class \u2013 CharField and EmailField are the only types of fields used here \u2013 as attributes of a Form class. Each field is required by default, so to make email optional, we specify required=False.<\/p>\n<p>Let\u2019s hop into the Python interactive interpreter and see what this class can do. The first thing it can do is display itself as HTML:<\/p>\n<p>(env_mysite) C:\\Users\\&#8230;\\mysite&gt; python manage.py shell<\/p>\n<p>&gt;&gt;&gt; from mysite.forms import ContactForm<br>\n&gt;&gt;&gt; f = ContactForm()<br>\n&gt;&gt;&gt; print(f)<br>\n&lt;tr&gt;&lt;th&gt;&lt;label for=&#8221;id_subject&#8221;&gt;Subject:&lt;\/label&gt;&lt;\/th&gt;&lt;td&gt;&lt;input type=&#8221;text&#8221; name=&#8221;subject&#8221; required id=&#8221;id_subject&#8221; \/&gt;&lt;\/td&gt;&lt;\/tr&gt;<br>\n&lt;tr&gt;&lt;th&gt;&lt;label for=&#8221;id_email&#8221;&gt;Email:&lt;\/label&gt;&lt;\/th&gt;&lt;td&gt;&lt;input type=&#8221;email&#8221; name=&#8221;email&#8221; id=&#8221;id_email&#8221; \/&gt;&lt;\/td&gt;&lt;\/tr&gt;<br>\n&lt;tr&gt;&lt;th&gt;&lt;label for=&#8221;id_message&#8221;&gt;Message:&lt;\/label&gt;&lt;\/th&gt;&lt;td&gt;&lt;input type=&#8221;text&#8221; name=&#8221;message&#8221; required id=&#8221;id_message&#8221; \/&gt;&lt;\/td&gt;&lt;\/tr&gt;<\/p>\n<p>Django adds a label to each field, along with &lt;label&gt; tags for accessibility. The idea is to make the default behavior as optimal as possible. This default output is in the format of an HTML &lt;table&gt;, but there are a few other built-in outputs:<\/p>\n<p>&gt;&gt;&gt; print(f.as_ul())<br>\n&lt;li&gt;&lt;label for=&#8221;id_subject&#8221;&gt;Subject:&lt;\/label&gt; &lt;input type=&#8221;text&#8221; name=&#8221;subject&#8221; required id=&#8221;id_subject&#8221; \/&gt;&lt;\/li&gt;<br>\n&lt;li&gt;&lt;label for=&#8221;id_email&#8221;&gt;Email:&lt;\/label&gt; &lt;input type=&#8221;email&#8221; name=&#8221;email&#8221; id=&#8221;id_email&#8221; \/&gt;&lt;\/li&gt;<br>\n&lt;li&gt;&lt;label for=&#8221;id_message&#8221;&gt;Message:&lt;\/label&gt; &lt;input type=&#8221;text&#8221; name=&#8221;message&#8221; required id=&#8221;id_message&#8221; \/&gt;&lt;\/li&gt;<\/p>\n<p>&gt;&gt;&gt; print(f.as_p())<br>\n&lt;p&gt;&lt;label for=&#8221;id_subject&#8221;&gt;Subject:&lt;\/label&gt; &lt;input type=&#8221;text&#8221; name=&#8221;subject&#8221; required id=&#8221;id_subject&#8221; \/&gt;&lt;\/p&gt;<br>\n&lt;p&gt;&lt;label for=&#8221;id_email&#8221;&gt;Email:&lt;\/label&gt; &lt;input type=&#8221;email&#8221; name=&#8221;email&#8221; id=&#8221;id_email&#8221; \/&gt;&lt;\/p&gt;<br>\n&lt;p&gt;&lt;label for=&#8221;id_message&#8221;&gt;Message:&lt;\/label&gt; &lt;input type=&#8221;text&#8221; name=&#8221;message&#8221; required id=&#8221;id_message&#8221; \/&gt;&lt;\/p&gt;<\/p>\n<p>Note that the opening and closing &lt;table&gt;, &lt;ul&gt; and &lt;form&gt; tags aren\u2019t included in the output, so that you can add any additional rows and customization if necessary. These methods are just shortcuts for the common case of displaying the entire form. You can also display the HTML for a particular field:<\/p>\n<p>&gt;&gt;&gt; print(f[&#8216;subject&#8217;])<br>\n&lt;input type=&#8221;text&#8221; name=&#8221;subject&#8221; required id=&#8221;id_subject&#8221; \/&gt;<br>\n&gt;&gt;&gt; print f[&#8216;message&#8217;]\n&lt;input type=&#8221;text&#8221; name=&#8221;message&#8221; required id=&#8221;id_message&#8221; \/&gt;<\/p>\n<p>The second thing Form objects can do is validate data. To validate data, create a new Form object and pass it a dictionary of data that maps field names to data:<\/p>\n<p>&gt;&gt;&gt; f = ContactForm({&#8216;subject&#8217;: &#8216;Hello&#8217;, &#8217;email&#8217;: &#8216;nige@example.com&#8217;, &#8216;message&#8217;: &#8216;Nice site!&#8217;})<\/p>\n<p>Once you\u2019ve associated data with a Form instance, you\u2019ve created a \u201cbound\u201d form:<\/p>\n<p>&gt;&gt;&gt; f.is_bound<br>\nTrue<\/p>\n<p>Call the is_valid() method on any bound Form to find out whether its data is valid. We\u2019ve passed a valid value for each field, so the Form in its entirety is valid:<\/p>\n<p>&gt;&gt;&gt; f.is_valid()<br>\nTrue<\/p>\n<p>If we don\u2019t pass the email field, it\u2019s still valid, because we\u2019ve specified required=False for that field:<\/p>\n<p>&gt;&gt;&gt; f = ContactForm({&#8216;subject&#8217;: &#8216;Hello&#8217;, &#8216;message&#8217;: &#8216;Nice site!&#8217;})<br>\n&gt;&gt;&gt; f.is_valid()<br>\nTrue<\/p>\n<p>But, if we leave off either subject or message, the Form is no longer valid:<\/p>\n<p>&gt;&gt;&gt; f = ContactForm({&#8216;subject&#8217;: &#8216;Hello&#8217;})<br>\n&gt;&gt;&gt; f.is_valid()<br>\nFalse<br>\n&gt;&gt;&gt; f = ContactForm({&#8216;subject&#8217;: &#8216;Hello&#8217;, &#8216;message&#8217;: &#8221;})<br>\n&gt;&gt;&gt; f.is_valid()<br>\nFalse<\/p>\n<p>You can drill down to get field-specific error messages:<\/p>\n<p>&gt;&gt;&gt; f = ContactForm({&#8216;subject&#8217;: &#8216;Hello&#8217;, &#8216;message&#8217;: &#8221;})<br>\n&gt;&gt;&gt; f[&#8216;message&#8217;].errors<br>\n[&#8216;This field is required.&#8217;]\n&gt;&gt;&gt; f[&#8216;subject&#8217;].errors<br>\n[ ]\n&gt;&gt;&gt; f[&#8217;email&#8217;].errors<br>\n[ ]\n<p>Each bound Form instance has an errors attribute that gives you a dictionary mapping field names to error-message lists:<\/p>\n<p>&gt;&gt;&gt; f = ContactForm({&#8216;subject&#8217;: &#8216;Hello&#8217;, &#8216;message&#8217;: &#8221;})<br>\n&gt;&gt;&gt; f.errors<br>\n{&#8216;message&#8217;`: [&#8216;This field is required.&#8217;]}<\/p>\n<p>Finally, for Form instances whose data has been found to be valid, a cleaned_data attribute is available. This is a dictionary of the submitted data, \u201ccleaned up\u201d. Django\u2019s forms framework not only validates data; it cleans it up by converting values to the appropriate Python types:<\/p>\n<p>&gt;&gt;&gt; f = ContactForm({&#8216;subject&#8217;: &#8216;Hello&#8217;, &#8217;email&#8217;: &#8216;nige@example.com&#8217;, &#8216;message&#8217;: &#8216;Nice site!&#8217;})<br>\n&gt;&gt;&gt; f.is_valid()<br>\nTrue<br>\n&gt;&gt;&gt; f.cleaned_data<br>\n{&#8216;subject&#8217;: &#8216;Hello&#8217;, &#8217;email&#8217;: &#8216;nige@example.com&#8217;, &#8216;message&#8217;: &#8216;Nice site!&#8217;}<\/p>\n<p>Our contact form only deals with strings, which are \u201ccleaned\u201d into string objects \u2013 but if we were to use an IntegerField or DateField, the forms framework would ensure that cleaned_data used proper Python integers or datetime.date objects for the given fields.<\/p>\n<h3>Tying Forms to Views<\/h3>\n<p>Our contact form is not much good to us unless we have some way of displaying it to the user. To do this, we need to first update our mysite\\views.py:<\/p>\n<p># mysite_project\\mysite\\mysite\\views.py<\/p>\n<p>from django.http import Http404, HttpResponse, HttpResponseRedirect<br>\nfrom django.shortcuts import render<br>\nimport datetime<br>\nfrom mysite.forms import ContactForm<br>\nfrom django.core.mail import send_mail, get_connection<\/p>\n<p># &#8230;<\/p>\n<p>def contact(request):<br>\nif request.method == &#8216;POST&#8217;:<br>\nform = ContactForm(request.POST)<br>\nif form.is_valid():<br>\ncd = form.cleaned_data<br>\ncon = get_connection(&#8216;django.core.mail.backends.console.EmailBackend&#8217;)<br>\nsend_mail(<br>\ncd[&#8216;subject&#8217;],<br>\ncd[&#8216;message&#8217;],<br>\ncd.get(&#8217;email&#8217;, &#8216;noreply@example.com&#8217;),<br>\n[&#8216;siteowner@example.com&#8217;],<br>\nconnection=con<br>\n)<br>\nreturn HttpResponseRedirect(&#8216;\/contact\/thanks\/&#8217;)<br>\nelse:<br>\nform = ContactForm()<\/p>\n<p>return render(request, &#8216;contact_form.html&#8217;, {&#8216;form&#8217;: form})<\/p>\n<p>We\u2019ve added the contact function to our view to handle the form submission. In this new function, we:<\/p>\n<ul>\n<li>&nbsp;Check to see if the request have been submitted with the POST method, otherwise we just display the blank form.<\/li>\n<li>We then check if the form contains valid data by calling the form\u2019s is_valid() method.<\/li>\n<li>If the form contains valid data, an email is sent and the user is redirected to a new view (\/contact\/thanks\/).<\/li>\n<li>If the form doesn\u2019t contain valid data, the if block jumps out to the final render() and the form is rendered back to the browser.<\/li>\n<\/ul>\n<p>Note that we don\u2019t do any error handling in the view \u2013 this is all handled by the form class. If the form doesn\u2019t validate, Django will automatically create a list of errors and append them to the response.<\/p>\n<p>A contact form is not much use without some way of sending the contact form information to the site owner. A very common way of doing this is to send an email. Django has the ability to send emails built in to the core. The email functions can be found in the django.core.mail module, which I have imported at the top of our modified views.py.<\/p>\n<p>We are using the send_mail() function to send the email to a dummy email address.<\/p>\n<p>To be able to display our contact form, we have to create our contact form (save this to mysite\\templates):<\/p>\n<p># mysite_project\\mysite\\templates\\contact_form.html<\/p>\n<p>&lt;html&gt;<br>\n&lt;head&gt;<br>\n&lt;title&gt;Contact us&lt;\/title&gt;<br>\n&lt;\/head&gt;<br>\n&lt;body&gt;<br>\n&lt;h1&gt;Contact us&lt;\/h1&gt;<\/p>\n<p>{% if form.errors %}<br>\n&lt;p style=&#8221;color: red;&#8221;&gt;<br>\nPlease correct the error{{ form.errors|pluralize }} below.<br>\n&lt;\/p&gt;<br>\n{% endif %}<\/p>\n<p>&lt;form action=&#8221;&#8221; method=&#8221;post&#8221; novalidate&gt;<br>\n&lt;table&gt;<br>\n{{ form.as_table }}<br>\n&lt;\/table&gt;<br>\n{% csrf_token %}<br>\n&lt;input type=&#8221;submit&#8221; value=&#8221;Submit&#8221;&gt;<br>\n&lt;\/form&gt;<br>\n&lt;\/body&gt;<br>\n&lt;\/html&gt;<\/p>\n<p>Since we\u2019re creating a POST form (which can have the effect of modifying data), we need to worry about Cross Site Request Forgeries. Thankfully, you don\u2019t have to worry too hard, because Django comes with a very easy-to-use system for protecting against it.<\/p>\n<p>In short, all POST forms that are targeted at internal URLs should use the {% csrf_token %} template tag.<\/p>\n<p>Keen-eyed readers will also notice the novalidate attribute in the &lt;form&gt; tag. When using HTML5 in some of the latest browsers (notably Chrome), form fields will be automatically validated by the browser. As we want Django to handle form validation, the novalidate attribute tells the browser not to validate the form.<\/p>\n<p>Finally, we need to change our urls.py to display our contact form at \/contact\/:<\/p>\n<p># &#8230;<br>\nfrom mysite.views import hello, current_datetime, hours_ahead, contact<\/p>\n<p>urlpatterns = [<br>\n# &#8230;<br>\nurl(r&#8217;^contact\/$&#8217;, contact),<br>\nurl(r&#8217;^&#8217;, include(&#8216;books.urls&#8217;)),<br>\n]\n<p>Try running this locally. Load the form, submit it with none of the fields filled out figure below, submit it with an invalid e-mail address (Figure 6-6), then finally submit it with valid data.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-128610 \" src=\"https:\/\/www.vskills.in\/lms\/wp-content\/uploads\/2016\/07\/31.jpg\" alt=\"\" width=\"665\" height=\"375\"><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-128611 size-full\" src=\"https:\/\/www.vskills.in\/lms\/wp-content\/uploads\/2016\/07\/32.jpg\" alt=\"\" width=\"1072\" height=\"450\"><\/p>\n<p>Note that you will get a \u201cPage not found (404)\u201d error when you submit the completed form. This is because I have not created the view or URLconf for the redirect to \/contact\/thanks\/. I will leave this to you as a learning exercise.<br>\nChanging How Fields Are Rendered<br>\nProbably the first thing you\u2019ll notice when you render this form locally is that the message field is displayed as an &lt;input type=&#8221;text&#8221;&gt;, and it ought to be a &lt;textarea&gt;. We can fix that by setting the field\u2019s widget:<\/p>\n<p>from django import forms<\/p>\n<p>class ContactForm(forms.Form):<br>\nsubject = forms.CharField()<br>\nemail = forms.EmailField(required=False)<br>\nmessage = forms.CharField(widget=forms.Textarea)<\/p>\n<p>The forms framework separates out the presentation logic for each field into a set of widgets. Each field type has a default widget, but you can easily override the default, or provide a custom widget of your own. Think of the Field classes as representing validation logic, while widgets represent presentation logic.<br>\nSetting a Maximum Length<br>\nOne of the most common validation needs is to check that a field is of a certain size. For good measure, we should improve our ContactForm to limit the subject to 100 characters. To do that, just supply a max_length to the CharField, like this:<\/p>\n<p>from django import forms<\/p>\n<p>class ContactForm(forms.Form):<br>\nsubject = forms.CharField(max_length=100)<br>\nemail = forms.EmailField(required=False)<br>\nmessage = forms.CharField(widget=forms.Textarea)<\/p>\n<p>An optional min_length argument is also available.<br>\nSetting Initial Values<br>\nAs an improvement to this form, let\u2019s add an initial value for the subject field: \u201cI love your site!\u201d (A little power of suggestion can\u2019t hurt.) To do this, we can use the initial argument when we create a Form instance:<\/p>\n<p>def contact(request):<\/p>\n<p># &#8230;<\/p>\n<p>else:<br>\nform = ContactForm(<br>\ninitial={&#8216;subject&#8217;: &#8216;I love your site!&#8217;}<br>\n)<\/p>\n<p>return render(request, &#8216;contact_form.html&#8217;, {&#8216;form&#8217;:form})<\/p>\n<p>Now, the subject field will be displayed pre-populated with that kind statement. Note that there is a difference between passing initial data and passing data that binds the form. The biggest difference is that if you\u2019re just passing initial data, then the form will be unbound, which means it won\u2019t have any error messages.<\/p>\n\n\n<p><a href=\"https:\/\/www.vskills.in\/certification\/tutorial\/certified-django-developer\/\" target=\"_blank\" rel=\"noreferrer noopener\">Back to Tutorial<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Once the user has filled the form to the point that it passes our validation rules, we need to do something useful with the data. In this case, we want to construct and send an email containing the user\u2019s feedback. We\u2019ll use Django\u2019s email package to do this. First, though, we need to tell if&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"categories":[8655],"tags":[8771],"class_list":["post-75672","page","type-page","status-publish","hentry","category-django-web-development","tag-processing-the-submission"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Processing the Submission - Tutorial<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.vskills.in\/certification\/tutorial\/processing-the-submission\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Processing the Submission - Tutorial\" \/>\n<meta property=\"og:description\" content=\"Once the user has filled the form to the point that it passes our validation rules, we need to do something useful with the data. In this case, we want to construct and send an email containing the user\u2019s feedback. We\u2019ll use Django\u2019s email package to do this. First, though, we need to tell if...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.vskills.in\/certification\/tutorial\/processing-the-submission\/\" \/>\n<meta property=\"og:site_name\" content=\"Tutorial\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/vskills.in\/\" \/>\n<meta property=\"article:modified_time\" content=\"2024-04-12T08:47:14+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.vskills.in\/lms\/wp-content\/uploads\/2016\/07\/31.jpg\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"16 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.vskills.in\/certification\/tutorial\/processing-the-submission\/\",\"url\":\"https:\/\/www.vskills.in\/certification\/tutorial\/processing-the-submission\/\",\"name\":\"Processing the Submission - Tutorial\",\"isPartOf\":{\"@id\":\"https:\/\/www.vskills.in\/certification\/tutorial\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.vskills.in\/certification\/tutorial\/processing-the-submission\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.vskills.in\/certification\/tutorial\/processing-the-submission\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.vskills.in\/lms\/wp-content\/uploads\/2016\/07\/31.jpg\",\"datePublished\":\"2020-01-20T05:59:11+00:00\",\"dateModified\":\"2024-04-12T08:47:14+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.vskills.in\/certification\/tutorial\/processing-the-submission\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.vskills.in\/certification\/tutorial\/processing-the-submission\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.vskills.in\/certification\/tutorial\/processing-the-submission\/#primaryimage\",\"url\":\"https:\/\/www.vskills.in\/lms\/wp-content\/uploads\/2016\/07\/31.jpg\",\"contentUrl\":\"https:\/\/www.vskills.in\/lms\/wp-content\/uploads\/2016\/07\/31.jpg\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.vskills.in\/certification\/tutorial\/processing-the-submission\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.vskills.in\/certification\/tutorial\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Processing the Submission\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.vskills.in\/certification\/tutorial\/#website\",\"url\":\"https:\/\/www.vskills.in\/certification\/tutorial\/\",\"name\":\"Tutorial\",\"description\":\"Vskills - A initiative in elearning and certification\",\"publisher\":{\"@id\":\"https:\/\/www.vskills.in\/certification\/tutorial\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.vskills.in\/certification\/tutorial\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.vskills.in\/certification\/tutorial\/#organization\",\"name\":\"Vskills\",\"url\":\"https:\/\/www.vskills.in\/certification\/tutorial\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.vskills.in\/certification\/tutorial\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.vskills.in\/certification\/tutorial\/wp-content\/uploads\/2017\/07\/vskills-min-logo.jpg\",\"contentUrl\":\"https:\/\/www.vskills.in\/certification\/tutorial\/wp-content\/uploads\/2017\/07\/vskills-min-logo.jpg\",\"width\":73,\"height\":55,\"caption\":\"Vskills\"},\"image\":{\"@id\":\"https:\/\/www.vskills.in\/certification\/tutorial\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/vskills.in\/\",\"https:\/\/x.com\/vskills_in\",\"https:\/\/www.linkedin.com\/company-beta\/1371554\/\",\"https:\/\/www.youtube.com\/channel\/UCMWnscxPwRF_PqXo9B7q_Tw\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Processing the Submission - Tutorial","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.vskills.in\/certification\/tutorial\/processing-the-submission\/","og_locale":"en_US","og_type":"article","og_title":"Processing the Submission - Tutorial","og_description":"Once the user has filled the form to the point that it passes our validation rules, we need to do something useful with the data. In this case, we want to construct and send an email containing the user\u2019s feedback. We\u2019ll use Django\u2019s email package to do this. First, though, we need to tell if...","og_url":"https:\/\/www.vskills.in\/certification\/tutorial\/processing-the-submission\/","og_site_name":"Tutorial","article_publisher":"https:\/\/www.facebook.com\/vskills.in\/","article_modified_time":"2024-04-12T08:47:14+00:00","og_image":[{"url":"https:\/\/www.vskills.in\/lms\/wp-content\/uploads\/2016\/07\/31.jpg","type":"","width":"","height":""}],"twitter_misc":{"Est. reading time":"16 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.vskills.in\/certification\/tutorial\/processing-the-submission\/","url":"https:\/\/www.vskills.in\/certification\/tutorial\/processing-the-submission\/","name":"Processing the Submission - Tutorial","isPartOf":{"@id":"https:\/\/www.vskills.in\/certification\/tutorial\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.vskills.in\/certification\/tutorial\/processing-the-submission\/#primaryimage"},"image":{"@id":"https:\/\/www.vskills.in\/certification\/tutorial\/processing-the-submission\/#primaryimage"},"thumbnailUrl":"https:\/\/www.vskills.in\/lms\/wp-content\/uploads\/2016\/07\/31.jpg","datePublished":"2020-01-20T05:59:11+00:00","dateModified":"2024-04-12T08:47:14+00:00","breadcrumb":{"@id":"https:\/\/www.vskills.in\/certification\/tutorial\/processing-the-submission\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.vskills.in\/certification\/tutorial\/processing-the-submission\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.vskills.in\/certification\/tutorial\/processing-the-submission\/#primaryimage","url":"https:\/\/www.vskills.in\/lms\/wp-content\/uploads\/2016\/07\/31.jpg","contentUrl":"https:\/\/www.vskills.in\/lms\/wp-content\/uploads\/2016\/07\/31.jpg"},{"@type":"BreadcrumbList","@id":"https:\/\/www.vskills.in\/certification\/tutorial\/processing-the-submission\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.vskills.in\/certification\/tutorial\/"},{"@type":"ListItem","position":2,"name":"Processing the Submission"}]},{"@type":"WebSite","@id":"https:\/\/www.vskills.in\/certification\/tutorial\/#website","url":"https:\/\/www.vskills.in\/certification\/tutorial\/","name":"Tutorial","description":"Vskills - A initiative in elearning and certification","publisher":{"@id":"https:\/\/www.vskills.in\/certification\/tutorial\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.vskills.in\/certification\/tutorial\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.vskills.in\/certification\/tutorial\/#organization","name":"Vskills","url":"https:\/\/www.vskills.in\/certification\/tutorial\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.vskills.in\/certification\/tutorial\/#\/schema\/logo\/image\/","url":"https:\/\/www.vskills.in\/certification\/tutorial\/wp-content\/uploads\/2017\/07\/vskills-min-logo.jpg","contentUrl":"https:\/\/www.vskills.in\/certification\/tutorial\/wp-content\/uploads\/2017\/07\/vskills-min-logo.jpg","width":73,"height":55,"caption":"Vskills"},"image":{"@id":"https:\/\/www.vskills.in\/certification\/tutorial\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/vskills.in\/","https:\/\/x.com\/vskills_in","https:\/\/www.linkedin.com\/company-beta\/1371554\/","https:\/\/www.youtube.com\/channel\/UCMWnscxPwRF_PqXo9B7q_Tw"]}]}},"_links":{"self":[{"href":"https:\/\/www.vskills.in\/certification\/tutorial\/wp-json\/wp\/v2\/pages\/75672","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.vskills.in\/certification\/tutorial\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.vskills.in\/certification\/tutorial\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.vskills.in\/certification\/tutorial\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.vskills.in\/certification\/tutorial\/wp-json\/wp\/v2\/comments?post=75672"}],"version-history":[{"count":4,"href":"https:\/\/www.vskills.in\/certification\/tutorial\/wp-json\/wp\/v2\/pages\/75672\/revisions"}],"predecessor-version":[{"id":83352,"href":"https:\/\/www.vskills.in\/certification\/tutorial\/wp-json\/wp\/v2\/pages\/75672\/revisions\/83352"}],"wp:attachment":[{"href":"https:\/\/www.vskills.in\/certification\/tutorial\/wp-json\/wp\/v2\/media?parent=75672"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.vskills.in\/certification\/tutorial\/wp-json\/wp\/v2\/categories?post=75672"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.vskills.in\/certification\/tutorial\/wp-json\/wp\/v2\/tags?post=75672"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}