Unit 4: Forms in Django - Subjective Questions
INT253 — Web Development In Python Using Django • Practice Questions with Detailed Answers
20 questions
Define a web form. Explain the purpose and main components of forms in Django.
A web form is an interface that allows users to enter and submit data to a web application. Django provides a Forms API for generating form controls, validating submitted data, and displaying validation errors.
Main components of a Django form:
- Form class: Defines the fields and validation rules of the form.
- Fields: Represent input values such as text, email addresses, integers, dates, and choices.
- Widgets: Determine how fields are rendered as HTML controls, such as text boxes, password boxes, and drop-down lists.
- Validation: Checks whether the submitted data satisfies field-level and form-level rules.
- Cleaned data: Validated and converted values are stored in
form.cleaned_data. - Errors: Validation errors are stored in
form.errorsand can be displayed to the user. - Template: Renders the form inside an HTML
<form>element. - View: Creates the form, receives submitted data, validates it, and processes valid input.
Django forms reduce repetitive coding and provide secure, consistent data handling.
Describe the complete form-processing cycle in a Django application.
The Django form-processing cycle consists of the following stages:
-
Display an empty form:
- The browser sends a GET request.
- The view creates an unbound form using
form = ContactForm(). - The form is rendered in a template.
-
Submit the form:
- The user enters data and submits the form.
- The browser sends the values, usually through a POST request.
-
Bind submitted data:
- The view creates a bound form using
form = ContactForm(request.POST). - Uploaded files, if present, are supplied through
request.FILES.
- The view creates a bound form using
-
Validate the data:
- The view calls
form.is_valid(). - Django performs field conversion, field validation, custom validation, and cross-field validation.
- The view calls
-
Process valid data:
- Validated values are read from
form.cleaned_data. - The application may save data, send an email, or perform another operation.
- Validated values are read from
-
Redirect after success:
- The view returns a redirect response to avoid duplicate submissions.
-
Redisplay invalid data:
- If validation fails, the same bound form is rendered again.
- Previously entered values and error messages are shown to the user.
Explain the GET method and its use in Django forms with a suitable example.
The GET method requests a resource and may send form data as part of the URL query string. It is normally used for operations that only retrieve information and do not change server-side data.
For example, submitting a search form may produce a URL such as /search/?query=django.
Template:
<form method="get" action="{% url 'search' %}">
<input type="text" name="query">
<button type="submit">Search</button>
</form>View:
def search(request):
query = request.GET.get('query', '')
results = Article.objects.filter(title__icontains=query)
return render(request, 'search.html', {
'query': query,
'results': results
})Characteristics of GET:
- Data is visible in the URL.
- URLs can be bookmarked and shared.
- It is suitable for searching, filtering, and pagination.
- It should not be used for passwords or confidential values.
- It should not create, update, or delete server-side data.
- Data is accessed through
request.GET, which is aQueryDict.
Explain the POST method and show how POST data is handled in a Django view.
The POST method sends submitted data in the HTTP request body. It is used when a request creates, updates, or otherwise changes server-side data.
A Django view can distinguish between initial display and form submission by checking request.method.
from django.shortcuts import render, redirect
from .forms import ContactForm
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
name = form.cleaned_data['name']
email = form.cleaned_data['email']
message = form.cleaned_data['message']
# Process or save the validated data
return redirect('contact_success')
else:
form = ContactForm()
return render(request, 'contact.html', {'form': form})Important points:
- Raw POST parameters are available through
request.POST. - A Django form should be used to validate and normalize the data.
- A POST form should include
{% csrf_token %}. - Sensitive operations should also require authentication and authorization.
- A redirect is recommended after successful processing.
Distinguish between GET and POST methods in the context of Django forms.
| Basis | GET | POST |
|---|---|---|
| Location of data | Query string of the URL | HTTP request body |
| Django object | request.GET |
request.POST |
| Primary purpose | Retrieving, searching, or filtering data | Creating or changing data |
| Visibility | Values are visible in the URL | Values are not placed in the URL query string |
| Bookmarking | Results can usually be bookmarked | Submission is not normally bookmarked |
| Caching | May be cached by browsers or intermediaries | Generally not cached in the same manner |
| CSRF protection | Safe GET operations normally do not require a CSRF token | State-changing POST forms require CSRF protection |
| Repeated request | Should not produce side effects | May repeat an operation unless duplicate submission is prevented |
| Typical examples | Search, filtering, sorting, pagination | Registration, login, feedback, database updates |
Security note: POST is not automatically encrypted. HTTPS is required to protect data while it travels between the browser and server.
GET should be safe and read-only, whereas POST should be used for operations that cause a server-side change.
Explain how HTTP requests and responses are represented and used by Django while processing forms.
Django represents an incoming HTTP request using an HttpRequest object and sends the result using an HttpResponse object or one of its subclasses.
Useful request attributes:
request.method: Contains the HTTP method, such asGETorPOST.request.GET: Contains query-string parameters as aQueryDict.request.POST: Contains submitted POST form values as aQueryDict.request.FILES: Contains uploaded files.request.user: Identifies the authenticated user.request.headers: Provides access to HTTP headers.
Common responses:
render(request, template, context)returns an HTML response.HttpResponse(content)returns direct response content.redirect(...)returns an HTTP redirect response.JsonResponse(data)returns JSON data.
In form processing, a GET request normally receives a blank form, while a POST request contains submitted values. The view validates those values and returns either an HTML page containing errors or a redirect response after successful processing.
Construct a Django form class for collecting a user's name, email address, age, and message. Explain the fields used.
A form can be defined by subclassing django.forms.Form:
from django import forms
class FeedbackForm(forms.Form):
name = forms.CharField(
max_length=100,
label='Full name'
)
email = forms.EmailField()
age = forms.IntegerField(
min_value=13,
max_value=120,
required=False
)
message = forms.CharField(
widget=forms.Textarea,
min_length=10
)Explanation:
CharFieldaccepts text.max_length=100limits the name length.EmailFieldchecks whether the input has a valid email-address structure.IntegerFieldconverts the submitted value to an integer and checks its permitted range.required=Falsemakes age optional.- The message uses a
Textareawidget so that a multi-line control is displayed. min_length=10requires a sufficiently descriptive message.
When is_valid() succeeds, Django places converted values in cleaned_data. For example, age is available as an integer rather than as raw text.
Describe different methods of rendering a Django form in a template. Why must the HTML <form> element be written explicitly?
Django provides several convenient form-rendering methods:
{{ form.as_p }}renders each field inside a paragraph element.{{ form.as_ul }}renders fields as list items; the surrounding<ul>must be supplied.{{ form.as_table }}renders fields as table rows; the surrounding<table>must be supplied.- Individual fields such as
{{ form.email }}can be rendered manually for complete layout control.
Example:
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Submit</button>
</form>Django renders fields, labels, help text, and validation errors, but it does not automatically generate the outer <form> element. The developer must specify:
- The HTTP
method, such aspostorget. - The submission
action, if it differs from the current URL. - The CSRF token for POST requests.
- The submit button.
enctype="multipart/form-data"when files are uploaded.
Manual rendering is useful when a project requires a custom design or field-specific error placement.
What are fields and widgets in Django forms? Compare their responsibilities with examples.
A field describes the type, validation rules, and normalization of a form value. A widget describes the HTML control used to display and collect that value.
Field responsibilities:
- Determines whether a value is required.
- Converts submitted text into a Python value.
- Performs built-in validation.
- Supports limits such as
min_value,max_value, andmax_length.
Widget responsibilities:
- Selects the HTML element used for input.
- Defines presentation attributes such as CSS classes and placeholders.
- Does not replace server-side validation.
from django import forms
class ProfileForm(forms.Form):
username = forms.CharField(
max_length=50,
widget=forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Enter username'
})
)
password = forms.CharField(widget=forms.PasswordInput)
birth_date = forms.DateField(widget=forms.DateInput(attrs={'type': 'date'}))
biography = forms.CharField(widget=forms.Textarea)For example, CharField performs text validation, while PasswordInput changes the visual HTML control so that the entered characters are hidden. Changing a widget does not change the underlying validation type.
Differentiate between bound and unbound forms in Django. How are errors and previously entered values preserved?
An unbound form has no submitted data attached to it. It is usually created for the initial GET request:
form = RegistrationForm()A bound form is associated with submitted data:
form = RegistrationForm(request.POST)Differences:
- An unbound form is normally blank or contains initial values.
- A bound form contains user-submitted values.
- Calling
is_valid()on a bound form runs validation. - A bound form can contain validation errors.
form.is_boundindicates whether data has been bound.
If validation fails, the view must render the same bound form:
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
return redirect('success')
else:
form = RegistrationForm()
return render(request, 'register.html', {'form': form})The bound form retains the submitted values and stores error messages in form.errors. Creating a new blank form after failure would discard both the user's input and the associated errors.
Write and explain a Django view that displays a form, validates POST data, and processes cleaned_data.
A typical function-based form view is:
from django.shortcuts import render, redirect
from .forms import FeedbackForm
def feedback(request):
if request.method == 'POST':
form = FeedbackForm(request.POST)
if form.is_valid():
name = form.cleaned_data['name']
email = form.cleaned_data['email']
message = form.cleaned_data['message'] # Save the data or perform another operation here.
return redirect('feedback_success')
else:
form = FeedbackForm()
return render(request, 'feedback/form.html', {'form': form})
Explanation:
- On GET, an unbound
FeedbackFormis created and displayed. - On POST,
request.POSTis passed to the form, producing a bound form. form.is_valid()executes the complete validation process.form.cleaned_datamust be accessed only after successful validation.- Values in
cleaned_dataare normalized Python values. - If validation fails, execution reaches
render()with the bound form, so errors are displayed. - If validation succeeds, the view performs the required operation and redirects to another URL.
This structure separates display, validation, processing, and successful navigation.
What is Cross-Site Request Forgery (CSRF)? Explain a typical CSRF attack and its possible consequences.
Cross-Site Request Forgery, or CSRF, is an attack in which a malicious website causes a user's browser to send an unwanted request to another website where the user is already authenticated.
Typical attack sequence:
- A user signs in to a trusted application, such as a banking or administration website.
- The browser stores the trusted application's session cookie.
- Without signing out, the user visits a malicious website.
- The malicious page causes the browser to submit a forged request to the trusted application.
- The browser may automatically attach the trusted application's cookies.
- If the server does not verify the request's origin, it may process the request as if the user intentionally submitted it.
Possible consequences:
- Changing an account email address or password.
- Modifying profile information.
- Creating or deleting records.
- Performing administrative operations.
- Initiating unauthorized transactions.
CSRF mainly threatens requests that change server-side state. Applications should not use GET requests for such operations and should protect POST forms with CSRF tokens.
Explain Django's CSRF protection mechanism and demonstrate how CSRF protection is included in a POST form.
Django provides built-in CSRF protection through CsrfViewMiddleware, CSRF tokens, and template support.
Protected template:
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Save</button>
</form>The {% csrf_token %} tag inserts a hidden field containing a token. During a state-changing request, Django checks whether the submitted token is valid for the current browser or session context.
Main steps:
- Django supplies a CSRF secret, commonly through a cookie.
- The template tag places a token in the rendered form.
- The browser submits the token with the POST data.
CsrfViewMiddlewarecompares and validates the submitted token.- If the check fails, Django rejects the request with an HTTP
403 Forbiddenresponse.
Requirements:
django.middleware.csrf.CsrfViewMiddlewareshould be enabled.- Templates must be rendered with the proper request context.
- Every internal POST form should include
{% csrf_token %}. - AJAX requests should send the CSRF token in the
X-CSRFTokenheader.
A CSRF token verifies that the state-changing request was generated through the application's trusted context.
What happens when Django's CSRF verification fails? Discuss safe practices and the risks of using csrf_exempt.
When CSRF verification fails, Django normally returns an HTTP 403 Forbidden response and does not execute the protected view. Failure may occur because the token is missing, invalid, incorrectly submitted, or inconsistent with the CSRF cookie.
Common causes:
{% csrf_token %}is missing from a POST form.- CSRF middleware is disabled or incorrectly ordered.
- An AJAX request does not include the
X-CSRFTokenheader. - Cookies are unavailable or blocked.
- The request originates from an untrusted origin.
The @csrf_exempt decorator disables CSRF checks for a view:
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def external_endpoint(request):
...Risks of csrf_exempt:
- It removes an important defense against forged requests.
- It may expose authenticated, state-changing operations.
- It can hide rather than correct an implementation problem.
Safe practices:
- Avoid
csrf_exemptfor normal browser forms. - Include CSRF tokens in all internal POST forms.
- Use HTTPS and secure cookie settings.
- For genuine external APIs or webhooks, use suitable authentication, signatures, or secret verification.
- Ensure GET requests remain read-only.
Explain the POST/Redirect/GET pattern. Why is it recommended after successful form submission?
The POST/Redirect/GET, or PRG, pattern is a web design technique used after a successful POST request.
Sequence:
- POST: The browser submits the form to the server.
- Redirect: After processing the data, the server returns an HTTP redirect response.
- GET: The browser follows the redirect and requests a result or success page using GET.
Benefits:
- Prevents accidental duplicate submission when the user refreshes the success page.
- Avoids the browser's form-resubmission warning in normal navigation.
- Creates a clean, bookmarkable result URL.
- Separates the data-changing request from the result display.
- Improves user experience and application flow.
Important limitation: PRG reduces accidental duplicate submissions but does not guarantee that every operation occurs only once. Critical operations may also require unique transaction identifiers, database constraints, or idempotency mechanisms.
If validation fails, the application should not redirect immediately. It should render the bound form in the same POST response so that field values and validation errors remain available.
Implement the POST/Redirect/GET pattern in Django using a form, view, URL configuration, and template.
Form:
python
forms.py
from django import forms
class MessageForm(forms.Form):
subject = forms.CharField(max_length=100)
message = forms.CharField(widget=forms.Textarea)
View:
python
views.py
from django.shortcuts import render, redirect
from .forms import MessageForm
def create_message(request):
if request.method == 'POST':
form = MessageForm(request.POST)
if form.is_valid():
Save or process form.cleaned_data here.
return redirect('message_success')
else:
form = MessageForm()
return render(request, 'messages/create.html', {'form': form})
def message_success(request):
return render(request, 'messages/success.html')
URL configuration:
python
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('messages/new/', views.create_message, name='create_message'),
path('messages/success/', views.message_success, name='message_success'),
]
Template:
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Send</button>
</form>The redirect is performed only after successful validation and processing. Invalid submissions render the bound form directly, preserving errors. The successful POST is followed by a GET request to message_success, implementing PRG.
Describe the data-validation process performed when is_valid() is called on a Django form.
Calling form.is_valid() triggers Django's form-cleaning and validation process. The method returns True only when the form is bound and contains no validation errors.
Main validation stages:
-
Field conversion:
- Each field converts raw input into an appropriate Python value.
- For example,
IntegerFieldconverts input text into an integer.
-
Field-level built-in validation:
- Django checks rules such as
required,max_length,min_value, and valid email structure.
- Django checks rules such as
-
Reusable validators:
- Functions supplied through the
validatorsargument are executed.
- Functions supplied through the
-
Field-specific cleaning methods:
- Methods such as
clean_email()perform custom validation for one field.
- Methods such as
-
Form-wide cleaning:
- The form's
clean()method validates relationships among multiple fields.
- The form's
-
Error collection:
ValidationErrorobjects are added to the appropriate fields or to non-field errors.
-
Creation of cleaned data:
- Successfully cleaned values are stored in
form.cleaned_data.
- Successfully cleaned values are stored in
Validation must always occur on the server. Browser-side validation can improve usability, but users can bypass it.
Explain three ways to implement custom validation in Django forms: validators, clean_<fieldname>(), and clean().
Django supports custom validation at different levels.
1. Reusable validator:
from django.core.exceptions import ValidationError
def validate_even(value):
if value % 2 != 0:
raise ValidationError('Enter an even number.')number = forms.IntegerField(validators=[validate_even])This approach is suitable when the same rule is used by multiple forms or fields.
2. Field-specific clean_<fieldname>():
def clean_username(self):
username = self.cleaned_data['username'].strip()
if username.lower() == 'admin':
raise forms.ValidationError('This username is reserved.')
return usernameThis method validates or transforms one field. It must return the cleaned value.
3. Form-wide clean():
def clean(self):
cleaned_data = super().clean()
start = cleaned_data.get('start_date')
end = cleaned_data.get('end_date')
if start and end and end < start:
raise forms.ValidationError(
'The end date cannot be earlier than the start date.'
)
return cleaned_dataThis method is appropriate for relationships involving multiple fields. Its errors are normally displayed as non-field errors.
Develop a password confirmation form using cross-field validation. Explain how validation errors should be displayed.
A password confirmation form must compare two related fields, so validation should be implemented in the form's clean() method.
from django import forms
class PasswordForm(forms.Form):
password = forms.CharField(
min_length=8,
widget=forms.PasswordInput
)
confirm_password = forms.CharField(
widget=forms.PasswordInput
)
def clean(self):
cleaned_data = super().clean()
password = cleaned_data.get('password')
confirmation = cleaned_data.get('confirm_password')
if password and confirmation and password != confirmation:
self.add_error(
'confirm_password',
'The two passwords do not match.'
)
return cleaned_dataExplanation:
super().clean()obtains values that passed individual field validation..get()is used because a value may be absent when its field has already failed validation.self.add_error()associates the error withconfirm_password.- Alternatively, raising
forms.ValidationErrorinclean()creates a non-field error.
Template display:
{{ form.non_field_errors }}
{{ form.password.errors }}
{{ form.password }}
{{ form.confirm_password.errors }}
{{ form.confirm_password }}The form must be processed only when form.is_valid() returns True.
Compare Form and ModelForm in Django. Illustrate how a ModelForm can validate and save database data securely.
Form and ModelForm both provide fields, widgets, validation, cleaned data, and error handling. Their main difference is their relationship with database models.
Form: Fields are declared manually. It is suitable for search, login, contact, and other forms not directly tied to a model.ModelForm: Fields and some validation rules are generated from a Django model. It can create or update model instances.
Example:
from django import forms
from .models import Article
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ['title', 'body', 'published']
def clean_title(self):
title = self.cleaned_data['title'].strip()
if len(title) < 5:
raise forms.ValidationError(
'The title must contain at least five characters.'
)
return titleView:
def create_article(request):
if request.method == 'POST':
form = ArticleForm(request.POST)
if form.is_valid():
article = form.save(commit=False)
article.author = request.user
article.save()
return redirect('article_detail', pk=article.pk)
else:
form = ArticleForm()
return render(request, 'articles/form.html', {'form': form})For security, explicitly list editable fields instead of exposing all model fields. Validation does not replace authorization; the view must still verify that the user is permitted to create or modify the object.
Define a web form. Explain the purpose and main components of forms in Django.
A web form is an interface that allows users to enter and submit data to a web application. Django provides a Forms API for generating form controls, validating submitted data, and displaying validation errors.
Main components of a Django form:
- Form class: Defines the fields and validation rules of the form.
- Fields: Represent input values such as text, email addresses, integers, dates, and choices.
- Widgets: Determine how fields are rendered as HTML controls, such as text boxes, password boxes, and drop-down lists.
- Validation: Checks whether the submitted data satisfies field-level and form-level rules.
- Cleaned data: Validated and converted values are stored in
form.cleaned_data. - Errors: Validation errors are stored in
form.errorsand can be displayed to the user. - Template: Renders the form inside an HTML
<form>element. - View: Creates the form, receives submitted data, validates it, and processes valid input.
Django forms reduce repetitive coding and provide secure, consistent data handling.
Did this save you a night before the exam?
LPU Notes is free, and it stays free. Ads cover part of the server bill. The rest comes out of a student's own pocket: the domain, the storage, and keeping the site up through the weeks everyone needs it at once.
The payment button didn't load. An ad blocker or a filtered network is the usual reason. to try again.
Nothing here is ever locked, and nothing unlocks. Chip in only if it was worth it. What it pays for →