Unit 3: Templates, Debugging and Testing - Subjective Questions
INT253 — Web Development In Python Using Django • Practice Questions with Detailed Answers
20 questions
Define a Django template. Explain its role in Django's Model-Template-View architecture.
A Django template is a text document, usually an HTML file, that defines how data should be presented to the user. It can contain static HTML as well as Django Template Language constructs for displaying dynamic data.
In Django's Model-Template-View (MTV) architecture:
- Model: Defines the structure of data and communicates with the database.
- Template: Controls the presentation and appearance of the response.
- View: Receives the request, obtains data from models, and passes that data to a template.
A typical rendering process is:
- The browser sends a request to a Django URL.
- The URL dispatcher calls the corresponding view.
- The view retrieves or processes data.
- The view passes the data to a template through a context dictionary.
- The template generates HTML and Django returns it as an HTTP response.
Example view:
return render(request, 'students/list.html', {'students': students})
Here, students/list.html is the template and students is a context variable available inside it.
Describe the steps required to create, configure, and render a template in a Django project.
The steps for creating and rendering a Django template are:
-
Create a template directory: Create a directory such as
templatesat the project level, or createtemplates/app_nameinside an application. -
Create the template file: For example, create
templates/students/home.htmlcontaining HTML and DTL expressions. -
Configure the template engine: In
settings.py, theTEMPLATESsetting must be configured. For a project-level directory, add:
'DIRS': [BASE_DIR / 'templates']
When application-level templates are used, keep 'APP_DIRS': True so Django searches the templates directory of installed applications.
- Create a view:
def home(request):
return render(request, 'students/home.html', {'title': 'Student Portal'})
- Define a URL pattern: Map a URL to the view in
urls.py.
path('', views.home, name='home')
- Use context data in the template:
<h1>{{ title }}</h1>
The render() shortcut loads the template, combines it with the context dictionary, and returns an HttpResponse containing the generated HTML.
Explain the main components of Django Template Language (DTL), with suitable examples.
Django Template Language provides a controlled syntax for inserting presentation logic into templates. Its main components are:
-
Variables: Display values passed through the context.
- Example:
{{ student.name }}
- Example:
-
Filters: Transform a variable before displaying it.
- Example:
{{ name|upper }} - Example:
{{ description|truncatewords:20 }}
- Example:
-
Tags: Perform template operations such as loops, conditions, inheritance, and URL generation.
- Example:
{% if user.is_authenticated %} - Example:
{% for student in students %}
- Example:
-
Comments: Prevent template content from being displayed.
- Single-line form:
{# This is a comment #} - Multi-line form:
{% comment %} ... {% endcomment %}
- Single-line form:
DTL intentionally provides limited programming features. Complex business logic should be placed in models, views, forms, or service functions rather than templates. This separation makes templates easier to read, maintain, and secure.
Explain how Django template variables are resolved. What happens when a variable does not exist?
A template variable is written using double braces, such as {{ variable }}. Django obtains its value from the context supplied by the view.
For a dotted expression such as {{ student.profile.city }}, Django generally attempts lookups in the following manner at each level:
- Dictionary lookup, such as
student['profile']. - Attribute or method lookup, such as
student.profile. - Numeric index lookup, when the component represents a list index.
Methods that require no arguments may be called automatically by the template system. However, template authors should avoid performing complex operations through such methods.
Examples:
{{ student.name }}accesses an attribute or dictionary key.{{ courses.0 }}accesses the first item in a sequence.{{ user.get_full_name }}may call a no-argument method.
If a variable cannot be resolved, Django normally displays an empty string rather than raising an error in the rendered page. This behavior can be customized with string_if_invalid in the template engine configuration, especially during debugging.
A default value can also be supplied using a filter:
{{ student.nickname|default:'Not provided' }}
What are Django template tags? Describe any five commonly used template tags.
Template tags are DTL instructions enclosed in {% and %}. They control template rendering and provide operations that are more complex than simple variable display.
Five commonly used tags are:
-
iftag: Conditionally renders content.{% if student.is_active %}Active{% endif %}
-
fortag: Iterates over a sequence.{% for course in courses %}{{ course.name }}{% endfor %}
-
extendstag: Declares that the current template inherits from a parent template.{% extends 'base.html' %}
-
blocktag: Defines a section that child templates can override.{% block content %}{% endblock %}
-
includetag: Inserts the rendered content of another template.{% include 'includes/navbar.html' %}
Other useful tags include url, csrf_token, load, with, comment, and cycle. Some tags are paired tags and must be closed with a corresponding tag such as {% endif %} or {% endfor %}.
Describe the use of the for tag in Django templates. Explain loop variables and the {% empty %} clause.
The {% for %} tag repeats a section of a template for every item in a sequence.
Example:
{% for student in students %}
<p>{{ forloop.counter }}. {{ student.name }}</p>
{% empty %}
<p>No students are available.</p>
{% endfor %}
Important loop variables include:
forloop.counter: Current iteration number starting from .forloop.counter0: Current iteration number starting from .forloop.revcounter: Number of iterations remaining, including the current one.forloop.first:Trueduring the first iteration.forloop.last:Trueduring the last iteration.forloop.parentloop: Refers to the outer loop in nested loops.
The {% empty %} clause is rendered when the sequence is empty or unavailable. It is usually cleaner than writing a separate if condition before the loop.
A dictionary may be iterated with:
{% for key, value in data.items %}
Nested loops are allowed, although complicated processing should generally be performed in the view.
Explain the syntax and working of if, elif, and else statements in Django templates. Mention the operators supported by DTL conditions.
Django templates use the {% if %} tag to render content conditionally.
Example:
{% if marks >= 75 %}
<p>Distinction</p>
{% elif marks >= 40 %}
<p>Pass</p>
{% else %}
<p>Fail</p>
{% endif %}
Commonly supported operators include:
- Comparison:
==,!=,<,>,<=, and>= - Membership:
inandnot in - Identity:
isandis not - Logical:
and,or, andnot
Example:
{% if user.is_authenticated and user.is_staff %}
Conditions can test variables directly. Values such as an empty string, an empty collection, None, and False are treated as false.
DTL does not support parentheses in conditions. When a condition becomes difficult to understand, nested if tags can be used, but complex decision-making should preferably be performed in the view and passed as a simple context value.
What are template filters in Django? Explain how filters are applied and describe any five built-in filters.
A template filter transforms or formats a variable before it is displayed. It is attached to a variable using the pipe symbol |.
General syntax:
{{ variable|filter_name }}
A filter may receive an argument:
{{ text|truncatewords:10 }}
Filters can also be chained:
{{ name|default:'Unknown'|upper }}
Five useful built-in filters are:
-
upper: Converts text to uppercase.{{ name|upper }}
-
lower: Converts text to lowercase.{{ email|lower }}
-
default: Supplies a fallback for a false or missing value.{{ city|default:'Not available' }}
-
date: Formats a date or time value.{{ created_at|date:'d M Y' }}
-
length: Returns the number of items or characters.{{ students|length }}
Other examples include title, join, truncatechars, truncatewords, floatformat, safe, and escape. The safe filter must be used cautiously because incorrectly marking user-controlled content as safe can introduce cross-site scripting vulnerabilities.
Explain how dynamic templates are created in Django by passing context data from a view. Illustrate the complete request-to-response flow.
A dynamic template generates different HTML according to data passed by a Django view.
Consider the following view:
def course_list(request):
courses = Course.objects.filter(is_active=True)
context = {'page_title': 'Available Courses', 'courses': courses}
return render(request, 'courses/list.html', context)
The template can display the supplied data:
<h1>{{ page_title }}</h1>
{% for course in courses %}
<p>{{ course.name }} - {{ course.fee }}</p>
{% empty %}
<p>No courses are available.</p>
{% endfor %}
The request-to-response flow is:
- A client sends an HTTP request.
- Django's URL dispatcher matches the request path.
- The selected view executes.
- The view may query models, validate input, or perform calculations.
- The view creates a context dictionary.
render()loads the specified template and combines it with the context.- DTL variables, filters, loops, and conditions are evaluated.
- The rendered HTML is returned inside an
HttpResponse.
Dynamic templates should focus on presentation. Database access and complex business logic should remain outside the template.
What is template inheritance in Django? Create a conceptual parent-child template structure and explain how it avoids duplication.
Template inheritance allows a common page structure to be defined in a parent template and customized by child templates. It reduces duplication of repeated elements such as headers, navigation bars, footers, and style references.
A parent template named base.html may contain:
<html>
<head><title>{% block title %}My Site{% endblock %}</title></head>
<body>
<nav>Common navigation</nav>
<main>{% block content %}{% endblock %}</main>
<footer>Common footer</footer>
</body>
</html>
A child template may contain:
{% extends 'base.html' %}
{% block title %}Student List{% endblock %}
{% block content %}
<h1>Students</h1>
{% endblock %}
Key points are:
{% extends %}identifies the parent template and should normally be the first template tag.{% block %}creates replaceable sections.- A child template overrides only the required blocks.
- Unchanged page sections are automatically inherited.
{{ block.super }}can be used to retain the parent block's content while adding child content.
This approach provides consistent design, easier maintenance, and centralized changes across multiple pages.
Distinguish between {% extends %}, {% block %}, and {% include %} in Django templates.
The three tags support template reuse, but they serve different purposes:
-
{% extends %}:- Establishes an inheritance relationship with a parent template.
- Used in a child template.
- Example:
{% extends 'base.html' %} - It is suitable for sharing the overall page layout.
-
{% block %}:- Defines a named section in a parent template that child templates may override.
- Example:
{% block content %}{% endblock %} - It works together with template inheritance.
-
{% include %}:- Renders and inserts another template at a specific location.
- Example:
{% include 'includes/student_card.html' with student=item %} - It is suitable for reusable components such as navigation bars, forms, cards, or messages.
Main distinction: Inheritance defines an overall parent-child layout, while inclusion composes a page from smaller reusable fragments. A block acts as an extension point within an inherited layout.
An included template usually receives the current context. The context can be restricted by using only, for example:
{% include 'includes/card.html' with student=item only %}
Explain the importance of automatic HTML escaping in Django templates. Compare the escape, safe, and autoescape features.
Django automatically escapes potentially dangerous HTML characters in template variables. This helps prevent cross-site scripting (XSS) attacks when content comes from users or other untrusted sources.
For example, if a variable contains a script element, {{ comment }} displays it as text rather than executing it in the browser.
The relevant features are:
-
Automatic escaping: Enabled by default for template variables. Characters such as
<,>,&, single quotes, and double quotes are converted to safe HTML entities. -
escapefilter: Explicitly escapes a value.- Example:
{{ content|escape }}
- Example:
-
safefilter: Marks a value as trusted HTML and prevents normal escaping.- Example:
{{ content|safe }} - It must not be applied to untrusted user input.
- Example:
-
autoescapetag: Enables or disables automatic escaping for a section.- Example:
{% autoescape off %}{{ content }}{% endautoescape %}
- Example:
The recommended practice is to keep automatic escaping enabled. HTML should be marked safe only when it has been generated or sanitized through a trusted process. Disabling escaping merely to correct display formatting can create a serious security vulnerability.
A view passes {'numbers': [2, 5, 8, 11]} to a template. Write and explain DTL logic that displays whether each number is even or odd and shows a message when the list is empty.
A suitable template is:
{% for number in numbers %}
{% if number|divisibleby:'2' %}
<p>{{ number }} is even.</p>
{% else %}
<p>{{ number }} is odd.</p>
{% endif %}
{% empty %}
<p>No numbers were supplied.</p>
{% endfor %}
The output for the given list is:
2 is even.5 is odd.8 is even.11 is odd.
Explanation:
{% for number in numbers %}iterates through the list.- The
divisiblebyfilter returns a truth value indicating whether the number is divisible by . {% if %}selects the even-number message when the remainder after division by is zero.{% else %}handles odd numbers.{% empty %}provides output whennumberscontains no items.
Although this example is appropriate for simple presentation logic, more complex classification or calculation should be completed in Python code before data is passed to the template.
Explain how Django's debugging mode works. Why must DEBUG be disabled in a production environment?
Django's debugging mode is controlled by the DEBUG setting in settings.py.
When DEBUG = True:
- Django displays detailed technical error pages.
- Tracebacks identify the files, functions, and lines involved in an exception.
- Request data and local variables may be shown.
- Template debugging information can help identify template-loading errors.
- Static files may be served conveniently during development when properly configured.
Debugging mode is useful for diagnosing errors such as:
TemplateDoesNotExistNoReverseMatch- Database exceptions
- Missing URL parameters
- Syntax errors and import errors
DEBUG must be set to False in production because detailed error pages can reveal sensitive information, including:
- Source-code structure
- Server paths
- Configuration values
- Request data
- Database details
- Internal variable values
In production, the application should instead use proper logging, custom error pages, secure exception monitoring, and correctly configured ALLOWED_HOSTS. Secret values should be stored in environment variables rather than directly in source code.
Describe a systematic procedure for debugging common Django template errors.
A systematic debugging procedure includes the following steps:
-
Read the traceback: Identify the exception type, template name, and highlighted line.
-
Check template paths: For
TemplateDoesNotExist, verify the file location, spelling, application namespace,TEMPLATES['DIRS'],APP_DIRS, andINSTALLED_APPS. -
Check DTL syntax: Confirm that tags are properly written and closed, such as
{% endif %},{% endfor %}, and{% endblock %}. -
Inspect context data: Verify that the view passes the expected variable names and types. A misspelled variable may silently render as an empty string.
-
Check inheritance: Ensure
{% extends %}points to the correct parent and block names match between parent and child templates. -
Check URL tags: A
NoReverseMatcherror usually indicates an incorrect URL name, namespace, or missing argument in{% url %}. -
Check custom tags: Confirm that the tag library is inside a
templatetagspackage, the app is installed, and{% load library_name %}is present. -
Use logging or temporary diagnostics: Log context values in the view rather than inserting complicated debugging logic in templates.
-
Create a minimal test case: Remove unrelated markup and reintroduce sections gradually.
-
Write a regression test: Once fixed, add a test that fails if the same problem returns.
Explain how logging can be used to debug a Django application. Compare logging with temporary print() statements.
Django uses Python's logging framework to record diagnostic and operational information.
A module can create a logger as follows:
import logging
logger = logging.getLogger(__name__)
Messages can then be recorded at different levels:
logger.debug(...): Detailed development information.logger.info(...): Normal application events.logger.warning(...): Unexpected situations that do not stop execution.logger.error(...): Errors that affect an operation.logger.exception(...): Error message together with the current traceback.logger.critical(...): Severe failures.
Compared with print() statements, logging provides:
- Configurable severity levels
- Output to consoles, files, email, or monitoring services
- Timestamps and module names
- Different configurations for development and production
- Better filtering and long-term diagnostics
Temporary print() statements may help with a very small local problem, but they are difficult to manage and may expose information or clutter production output. Logging is the preferred method.
Sensitive data such as passwords, tokens, cookies, and personal information should never be written to logs. Production logging should provide enough context to investigate failures without exposing confidential data.
Define testing in Django. Explain the structure and life cycle of a test case created using django.test.TestCase.
Testing is the process of automatically verifying that application components behave as expected. Django integrates with Python's unittest framework and provides additional tools for databases, HTTP requests, templates, forms, and email.
A basic test class is:
from django.test import TestCase
class CourseTests(TestCase):
@classmethod
def setUpTestData(cls):
cls.course = Course.objects.create(name='Python')
def setUp(self):
self.client.login(username='user', password='secret')
def test_course_name(self):
self.assertEqual(self.course.name, 'Python')
Important stages are:
- Test discovery: Django finds files whose names begin with
test. - Test database creation: A separate database is created so production data is not modified.
- Class-level setup:
setUpTestData()creates data once for the class. - Per-test setup:
setUp()runs before every test method. - Execution: Methods whose names begin with
test_are run. - Assertions: Methods such as
assertEqual()determine whether behavior is correct. - Isolation and cleanup: Database changes are isolated and rolled back or reset.
- Test database destruction: The temporary database is removed after the test run.
Tests are commonly executed with python manage.py test.
Describe how Django's test client can be used to test a view, its status code, template, context, and rendered content.
Django's test client simulates HTTP requests without requiring a running web server. It is available as self.client in a TestCase.
Example:
from django.test import TestCase
from django.urls import reverse
class StudentListViewTests(TestCase):
def test_student_list(self):
response = self.client.get(reverse('students:list'))
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'students/list.html')
self.assertIn('students', response.context)
self.assertContains(response, 'Student List')
The test verifies:
- URL behavior:
reverse()generates the URL from its registered name. - Status code: A successful response normally has status code
200. - Template selection:
assertTemplateUsed()confirms the expected template was rendered. - Context data:
response.contextexposes context variables supplied to the template. - Rendered content:
assertContains()checks the generated response body.
Redirects can be tested with assertRedirects(). POST requests can be simulated with self.client.post(url, data). Authentication can be tested with self.client.login(), self.client.logout(), or self.client.force_login(user).
Distinguish between unit testing, integration testing, and functional testing in the context of a Django application.
The three testing levels differ mainly in scope:
-
Unit testing:
- Tests a small component in isolation.
- Examples include a model method, form validator, utility function, or custom template filter.
- It is generally fast and helps identify failures precisely.
-
Integration testing:
- Tests whether multiple Django components work together.
- Examples include testing URL resolution, view execution, database queries, context creation, template rendering, and redirects in one request.
- Django's test client is commonly used for this level.
-
Functional or end-to-end testing:
- Tests complete user workflows from the user's perspective.
- Examples include logging in, submitting a form, navigating to a list page, and confirming the displayed result.
- Tools such as Selenium may be used with Django's
LiveServerTestCase.
A balanced test suite normally contains many fast unit tests, a smaller number of integration tests, and selected functional tests for critical workflows. Unit tests provide speed and precision, while broader tests provide confidence that the complete system operates correctly.
Design a comprehensive testing strategy for a Django page that displays a dynamic student list using template inheritance, loops, and conditional statements.
A comprehensive strategy should test the page at several levels.
1. Model and data tests
- Verify that student objects are created correctly.
- Test model methods used by the view or template.
- Check ordering and filtering rules.
2. URL tests
- Use
reverse()to verify the named URL. - Confirm that the URL resolves to the expected view.
3. View tests
- Send a GET request with
self.client.get(). - Assert status code
200. - Verify that the correct student queryset is included in the context.
- Test authentication or permission requirements where applicable.
4. Template tests
- Use
assertTemplateUsed()for both the child template and, when appropriate, the inherited parent template. - Confirm that common inherited content such as the navigation bar or page title is present.
5. Loop tests
- Create multiple students and verify that each name appears.
- Check ordering if the page promises a specific order.
- Confirm that excluded students are not displayed.
6. Conditional tests
- Test the empty-list case and verify the
{% empty %}message. - Test conditions such as active versus inactive students.
- Test content visible only to authenticated or staff users.
7. Response and security tests
- Verify that special characters are escaped correctly.
- Test missing pages, invalid parameters, and unauthorized access.
- Confirm expected redirects and error status codes.
8. Regression tests
- Add a test whenever a template, context, or rendering defect is fixed.
This strategy verifies not only individual components but also the complete interaction among models, views, context data, DTL logic, template inheritance, and the generated response.
Define a Django template. Explain its role in Django's Model-Template-View architecture.
A Django template is a text document, usually an HTML file, that defines how data should be presented to the user. It can contain static HTML as well as Django Template Language constructs for displaying dynamic data.
In Django's Model-Template-View (MTV) architecture:
- Model: Defines the structure of data and communicates with the database.
- Template: Controls the presentation and appearance of the response.
- View: Receives the request, obtains data from models, and passes that data to a template.
A typical rendering process is:
- The browser sends a request to a Django URL.
- The URL dispatcher calls the corresponding view.
- The view retrieves or processes data.
- The view passes the data to a template through a context dictionary.
- The template generates HTML and Django returns it as an HTTP response.
Example view:
return render(request, 'students/list.html', {'students': students})
Here, students/list.html is the template and students is a context variable available inside it.
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 →