Django Scenario-Based Multiple Choice
Questions
User Authentication and Authorization
Scenario 1:
You're building an e-commerce platform where users can view their order history. You
want to ensure only authenticated users can access their order details.
def order_history(request):
orders = Order.objects.filter(user=request.user)
return render(request, 'orders/history.html', {'orders': orders})
Q1. Which decorator should you add to make this view accessible only to logged-in
users?
a) @login_required
b) @user_passes_test
c) @permission_required
d) @authentication_required
Answer: a) @login_required
Explanation: The @login_required decorator is the simplest way to ensure a view is
only accessible to authenticated users. It will redirect unauthorized users to the login
page.
Scenario 2:
In your e-commerce system, some users should be able to process refunds while others
can only view orders.
Q2. What's the best way to implement this permission system?
a) Create a custom middleware
b) Use Django's built-in permissions system
c) Check user.is_staff in views
d) Store permissions in session variables
Answer: b) Use Django's built-in permissions system
Explanation: Django's permission system allows you to create granular permissions
that can be assigned to users and groups, making it ideal for role-based access
control.
Models and Database
Scenario 3:
You're building a blog where posts can have multiple categories. Your models look like
this:
class Category(models.Model):
name = models.CharField(max_length=100)
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
categories = models.ManyToManyField(Category)
Q3. To get all posts in a specific category, which query is most efficient?
a) Post.objects.filter(categories__name=category_name)
b) Category.objects.get(name=category_name).post_set.all()
c) Post.objects.all().filter(lambda x: category_name in x.categories.all())
d) [post for post in Post.objects.all() if category_name in
post.categories.values_list('name', flat=True)]
Answer: a) Post.objects.filter(categories__name=category_name)
Explanation: This query uses Django's lookup spanning relationships and will be
translated into an efficient SQL JOIN operation.
Forms and Validation
Scenario 4:
You have a contact form where users can submit messages:
class ContactForm(forms.ModelForm):
class Meta:
model = Contact
fields = ['name', 'email', 'message']
Q4. A user reports that they're receiving spam messages with invalid email addresses.
How should you validate the email field?
a) Add a regex pattern in the model field
b) Use Django's built-in EmailField
c) Write a custom clean_email() method
d) Add JavaScript validation
Answer: b) Use Django's built-in EmailField
Explanation: Django's EmailField provides built-in validation for email addresses and is
the most reliable solution, as it handles various edge cases and follows email
standards.
URLs and Routing
Scenario 5:
You're building an API that needs to handle different versions:
Q5. What's the most Django-like way to structure your URLs for API versioning?
a) Include version in URL path: /api/v1/users/
b) Use query parameters: /api/users/?version=1
c) Use custom middleware to handle version headers
d) Create separate Django apps for each version
Answer: a) Include version in URL path: /api/v1/users/
Explanation: This is the most explicit and REST-compliant approach, making it clear
which version is being accessed and allowing for easy URL-based routing.
Template System
Scenario 6:
You have a base template that multiple pages extend, but some pages need different CSS
files.
Q6. What's the best way to allow child templates to add their own CSS files?
a) Use different base templates for different CSS needs
b) Include all possible CSS files in the base template
c) Use template blocks and the {{ block.super }} feature
d) Load CSS files dynamically with JavaScript
Answer: c) Use template blocks and the {{ block.super }} feature
Explanation: Using template blocks allows child templates to add their own CSS while
maintaining the base template's styles.
Middleware and Request Processing
Scenario 7:
You need to track the time spent on each request for performance monitoring.
Q7. Which approach would be most appropriate?
a) Add timing code to each view
b) Create custom middleware
c) Use template tags
d) Modify the URLconf
Answer: b) Create custom middleware
Explanation: Middleware can process requests and responses globally, making it
perfect for timing all requests without modifying individual views.
Static Files and Media
Scenario 8:
Your application needs to handle user-uploaded files and serve them securely.
Q8. Which configuration is most secure for handling user uploads?
a) Store files in the static directory with Django's static files
b) Use Django's FileField with proper storage backend configuration
c) Save files directly to the server's file system
d) Store all files in the database as binary data
Answer: b) Use Django's FileField with proper storage backend configuration
Explanation: FileField provides built-in handling for uploads, can be configured with
various storage backends (like S3), and can implement security measures like access
control.
Advanced Django ORM
Scenario 9:
You need to optimize a query that aggregates data across multiple related models:
class Order(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
items = models.ManyToManyField(Product, through='OrderItem')
created_at = models.DateTimeField(auto_now_add=True)
class OrderItem(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
quantity = models.IntegerField()
price = models.DecimalField(max_digits=10, decimal_places=2)
Q19. Which query would most efficiently get the total revenue per customer for the last
month?
a) Use multiple separate queries with Python aggregation
b) Use annotate() with F() expressions and Sum()
c) Write a raw SQL query
d) Use values() with a loop
Answer: b) Use annotate() with F() expressions and Sum()
Explanation: This approach leverages Django's ORM to perform efficient database-level
aggregation:
Customer.objects.annotate(
revenue=Sum(
F('order__orderitem__quantity') * F('order__orderitem__price'),
filter=Q(order__created_at__gte=one_month_ago)
)
)
Scenario 10:
You're implementing a recursive category structure for a product catalog:
class Category(models.Model):
name = models.CharField(max_length=100)
parent = models.ForeignKey('self', null=True, on_delete=models.CASCADE)
def get_all_subcategories(category_id):
# Implementation needed
pass
Q20. What's the most efficient way to query all subcategories (including nested ones)?
a) Use recursive queries with Django's With()
b) Implement a recursive function with multiple queries
c) Use django-mptt
d) Store the full path in a separate field
Answer: c) Use django-mptt
Explanation: django-mptt implements Modified Preorder Tree Traversal, providing
efficient tree operations and querying of hierarchical data structures.
Design Patterns in Django
Scenario 11:
You need to implement different payment processing strategies (PayPal, Stripe, etc.) in
your e-commerce application:
class PaymentProcessor:
def process_payment(self, amount):
# Implementation needed
pass
Q21. Which design pattern would be most appropriate?
a) Observer Pattern
b) Strategy Pattern
c) Factory Pattern
d) Singleton Pattern
Answer: b) Strategy Pattern
Explanation: The Strategy Pattern allows you to define a family of algorithms (payment
processors), encapsulate each one, and make them interchangeable at runtime.
Python Memory Management
Scenario 12:
You're working with large datasets and notice memory usage growing:
def process_large_file(filename):
data = []
with open(filename) as f:
for line in f:
data.append(process_line(line))
return data
Q22. How would you optimize this for memory efficiency?
a) Use list comprehension instead of append
b) Use a generator function
c) Use multiprocessing
d) Increase Python's memory limit
Answer: b) Use a generator function
Explanation: Generator functions yield items one at a time instead of storing them all
in memory:
def process_large_file(filename):
with open(filename) as f:
for line in f:
yield process_line(line)
Advanced Authentication
Scenario 13:
You need to implement multi-factor authentication in your Django application:
class CustomAuthBackend:
def authenticate(self, request, username=None, password=None, token=None):
# Implementation needed
pass
Q23. Which approach would be most secure and maintainable?
a) Custom session middleware
b) Django REST Knox with custom token backend
c) JWT with custom claims
d) Custom authentication backend with TOTP
Answer: d) Custom authentication backend with TOTP
Explanation: Using a custom authentication backend with Time-based One-Time
Passwords (TOTP) provides a standardized and secure approach to 2FA, compatible
with authenticator apps.
Asynchronous Programming
Scenario 14:
You need to implement a real-time notification system:
async def notify_users(message):
# Implementation needed for sending notifications
# to multiple users simultaneously
pass
Q24. Which approach would be most scalable?
a) Django Channels with WebSocket consumers
b) Periodic AJAX polling
c) Server-Sent Events
d) Long polling with threads
Answer: a) Django Channels with WebSocket consumers
Explanation: Django Channels provides a robust framework for handling WebSocket
connections, with built-in support for scaling across multiple workers and machines
using channel layers.
Performance Optimization
Scenario 15:
Your Django application is experiencing slow response times for complex database
queries:
def get_dashboard_data(user_id):
# Complex query involving multiple joins and calculations
result = (
Order.objects.filter(user_id=user_id)
.annotate(
total=Sum('items__price'),
item_count=Count('items')
)
.prefetch_related('items')
)
Q25. Which caching strategy would be most effective?
a) Cache the entire queryset
b) Use Redis with selective invalidation
c) Implement memcached with per-user keys
d) Use local memory caching
Answer: b) Use Redis with selective invalidation
Explanation: Redis provides fast access, atomic operations, and supports complex
data structures. With selective invalidation, you can invalidate only the affected user's
cache when their data changes:
def get_dashboard_data(user_id):
cache_key = f'dashboard_data_{user_id}'
data = cache.get(cache_key)
if data is None:
data = compute_dashboard_data(user_id)
cache.set(cache_key, data, timeout=3600)
return data
API Design
Scenario 16:
You need to implement rate limiting for your API:
class APIView(View):
def get(self, request, *args, **kwargs):
# Need to implement rate limiting
return JsonResponse({"data": "response"})
Q26. Which implementation would be most robust?
a) Custom middleware with Redis
b) Django REST framework's throttling classes
c) Database-backed rate limiting
d) In-memory counter
Answer: b) Django REST framework's throttling classes
Explanation: DRF's throttling classes provide a battle-tested solution with support for
various strategies (per-user, per-IP, etc.) and can be easily customized.
Advanced Django REST Framework
Scenario 17:
You're building an API that needs to handle complex filtering with multiple parameters.
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
Q9. Which DRF feature should you implement for flexible filtering?
a) Custom filter_queryset method
b) Django Filter Backend
c) SearchFilter
d) Custom middleware
Answer: b) Django Filter Backend
Explanation: Django Filter Backend provides a powerful and flexible way to filter
querysets based on URL parameters, supporting complex filtering with minimal code.
Scenario 18:
You need to implement caching in your Django application for better performance.
Q10. Which caching strategy would be most appropriate for frequently accessed, rarely
modified data?
a) Per-view caching
b) Template fragment caching
c) Cache entire site
d) Database query caching
Answer: b) Template fragment caching
Explanation: Template fragment caching allows you to cache specific parts of a
template that are expensive to generate and don't change often, while still keeping
other parts dynamic.
Python Data Structures and Algorithms
Scenario 19:
You need to implement a function that finds pairs of numbers in a list that sum to a target
value.
def find_pairs(numbers, target):
# Implementation needed
pass
Q11. Which approach would be most efficient for large lists?
a) Nested loops (O(n²))
b) Sorting and two pointers (O(n log n))
c) Hash table (O(n))
d) Binary search for each number (O(n log n))
Answer: c) Hash table (O(n))
Explanation: Using a hash table allows us to find pairs in a single pass through the
array, giving us O(n) time complexity with O(n) space complexity.
Scenario 20:
You're implementing a cache with a fixed size that removes the least recently used item
when full.
Q12. Which data structures would be most appropriate for implementing an LRU cache?
a) Array and Queue
b) Dictionary and Doubly Linked List
c) Binary Search Tree
d) Stack and Set
Answer: b) Dictionary and Doubly Linked List
Explanation: A dictionary provides O(1) lookups while a doubly linked list allows O(1)
removal and addition of elements, making this combination perfect for an LRU cache.
Python Concurrency and Async
Scenario 21:
You need to scrape data from multiple APIs concurrently.
async def fetch_data(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.json()
Q13. Which approach would be most efficient?
a) Use threading.Thread
b) Use multiprocessing.Pool
c) Use asyncio and aiohttp
d) Sequential requests with requests library
Answer: c) Use asyncio and aiohttp
Explanation: For I/O-bound tasks like API calls, asyncio provides non-blocking
operations that can handle many concurrent connections efficiently.
Scenario 22:
You're processing a large dataset with CPU-intensive calculations.
Q14. Which Python feature would be most appropriate?
a) asyncio.gather()
b) multiprocessing.Pool
c) threading.Thread
d) concurrent.futures.ThreadPoolExecutor
Answer: b) multiprocessing.Pool
Explanation: For CPU-bound tasks, multiprocessing allows true parallel execution by
utilizing multiple CPU cores, bypassing the GIL limitation.
Database Optimization
Scenario 23:
Your Django application is making too many database queries when displaying a list of
articles with their authors and categories.
class Article(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(User, on_delete=models.CASCADE)
categories = models.ManyToManyField(Category)
def article_list(request):
articles = Article.objects.all()
return render(request, 'articles/list.html', {'articles': articles})
Q15. How would you optimize this to reduce database queries?
a) Use raw SQL queries
b) Add select_related() and prefetch_related()
c) Cache the entire queryset
d) Use values() and values_list()
Answer: b) Add select_related() and prefetch_related()
Explanation: select_related() for ForeignKey (author) and prefetch_related() for
ManyToManyField (categories) will optimize the queries by fetching related data in
fewer queries.
Security Best Practices
Scenario 24:
You're storing sensitive user data in your Django application.
Q16. Which security measure is most critical for protecting passwords?
a) Store encrypted passwords using reversible encryption
b) Use SHA-256 hashing
c) Use Django's default password hasher (PBKDF2)
d) Store passwords in environment variables
Answer: c) Use Django's default password hasher (PBKDF2)
Explanation: Django's password hasher uses PBKDF2 with a SHA256 hash, which
includes salt and multiple iterations, making it highly secure against various attacks.
Testing and Debugging
Scenario 25:
You need to test a view that requires authentication and specific permissions.
class TestArticleView(TestCase):
def test_article_creation(self):
# Test implementation needed
pass
Q17. Which testing approach is most appropriate?
a) Use Django's test client with setUp
b) Mock the authentication system
c) Test without authentication
d) Use external testing service
Answer: a) Use Django's test client with setUp
Explanation: Django's test client with setUp allows you to create test users with
specific permissions and simulate authenticated requests effectively.
Django REST Framework Authentication
Scenario 26:
You're building a mobile API where users need to authenticate using tokens.
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
Q26. Which authentication class should you use for mobile API token authentication?
a) BasicAuthentication
b) SessionAuthentication
c) TokenAuthentication
d) JWTAuthentication
Answer: c) TokenAuthentication
TokenAuthentication is ideal for client-server setups like mobile apps, providing a
secure way to authenticate API requests using tokens that can be stored safely on
mobile devices.
API Throttling
Scenario 27:
Your API is being hit with too many requests from certain users.
class UserAPI(APIView):
permission_classes = [IsAuthenticated]
def get(self, request):
return Response({"data": "sensitive information"})
Q2. How should you implement rate limiting for this API?
a) Use custom middleware
b) Add throttle_classes = [UserRateThrottle]
c) Implement caching
d) Use @ratelimit decorator
Answer: b) Add throttle_classes = [UserRateThrottle]
DRF's built-in throttling classes provide a clean way to limit API request rates per
user or IP address.
Serializers and Validation
Scenario 28:
You have a nested serializer for an order system:
class OrderSerializer(serializers.ModelSerializer):
items = OrderItemSerializer(many=True)
class Meta:
model = Order
fields = ['id', 'user', 'items', 'total']
Q3. How should you handle creating an order with multiple items in a single request?
a) Override create() method with @transaction.atomic
b) Use multiple API calls
c) Create a custom field
d) Use a standard ModelSerializer
Answer: a) Override create() method with @transaction.atomic
Using @transaction.atomic ensures all items are created together or none at all,
maintaining database integrity.
Cache Management
Scenario 29:
Your Django application's product listing page is loading slowly due to complex database
queries.
Q4. What's the most efficient caching strategy for this situation?
a) Use per-view caching
b) Implement cache middleware
c) Use template fragment caching
d) Cache the entire site
Answer: c) Use template fragment caching
Template fragment caching allows you to cache specific parts of the template that
are expensive to generate while keeping other parts dynamic:
{% load cache %}
{% cache 300 product_list %}
{# Complex product listing HTML here #}
{% endcache %}
API Versioning
Scenario 30:
You need to make breaking changes to your API while maintaining backward compatibility.
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
Q5. Which DRF versioning scheme should you use if you want to maintain versions
through URLs?
a) URLPathVersioning
b) NamespaceVersioning
c) AcceptHeaderVersioning
d) QueryParameterVersioning
Answer: a) URLPathVersioning
URLPathVersioning (like `/api/v2/users/`) is explicit and makes it clear which
version is being accessed, making it easier for clients to understand and use.
Background Tasks
Scenario 31:
Your e-commerce site needs to send confirmation emails after orders are placed.
Q6. What's the best way to handle these email notifications?
a) Send emails directly in the view
b) Use Django signals
c) Use Celery tasks
d) Use a custom middleware
Answer: c) Use Celery tasks
Celery allows you to handle email sending asynchronously, preventing delays in the
request-response cycle and handling failures gracefully.
Custom Management Commands
Scenario 32:
You need to create a daily data cleanup task.
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = 'Cleans up old data'
Q7. What's the best way to make this command handle errors and provide feedback?
a) Use print statements
b) Use logging
c) Use self.stdout.write()
d) Raise exceptions
Answer: c) Use self.stdout.write()
Django's management commands should use self.stdout.write() for output, as it
handles different verbosity levels and works well with testing.
API Filtering
Scenario 33:
You have an API endpoint that needs to filter products by multiple criteria.
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
Q8. Which DRF feature should you use for complex filtering?
a) Custom filter backend
b) Django-filter integration
c) Override get_queryset()
d) Use Q objects directly
Answer: b) Django-filter integration
Django-filter with DRF provides a powerful, declarative way to filter querysets based
on URL parameters:
from django_filters import rest_framework as filters
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
filter_backends = (filters.DjangoFilterBackend,)
filterset_fields = ['category', 'price', 'in_stock']
Permissions
Scenario 34:
You have an API where users can create posts, but only edit their own posts.
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
Q9. How should you implement this permission logic?
a) Override get_queryset()
b) Create custom permission class
c) Use IsAuthenticated
d) Check in serializer
Answer: b) Create custom permission class
Custom permission classes provide a clean way to implement object-level
permissions:
class IsOwnerOrReadOnly(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
return obj.user == request.user
API Documentation
Scenario 35:
Your team needs to document the API for external developers.
Q10. What's the most maintainable way to document your DRF APIs?
a) Write separate documentation
b) Use drf-yasg
c) Create markdown files
d) Use function docstrings
Answer: b) Use drf-yasg
drf-yasg automatically generates OpenAPI/Swagger documentation from your
ViewSets and Serializers, keeping documentation in sync with code:
@swagger_auto_schema(
operation_description="Create a new user",
responses={201: UserSerializer}
)
def create(self, request):
...
Scenario 36:
Which view type should you use for this basic listing?
a) TemplateView
b) ListView
c) DetailView
d) FormView
Answer: b) ListView
ListView is best suited for displaying a list of items. It automatically provides the
necessary context data to render lists, like products.
Scenario 37:
Which field should you use for storing publication dates?
a) DateField
b) DateTimeField
c) CharField
d) IntegerField
Answer: b) DateTimeField
DateTimeField stores both the date and time, which is useful for blog posts to
record the precise publication timestamp.
Scenario 38:
Which function is commonly used to handle form submissions and validate the data?
a) cleaned_data
b) is_valid()
c) save()
d) process_data()
Answer: b) is_valid()
is_valid() checks if form data meets validation criteria before processing or saving
it.
Scenario 39:
Which utility would you use to construct URLs in Django templates?
a) include
b) reverse
c) url
d) path
Answer: c) url
{% url 'view-name' args %} is used in Django templates to generate URLs
dynamically based on the view's name and parameters.
Scenario 40:
Where should you implement this user-specific filtering logic?
a) In the model
b) In the view's get_queryset()
c) In the serializer
d) In the URLconf
Answer: b) In the view's get_queryset()
Filtering by user in get_queryset() keeps the view logic clean and focuses on data
that only the current user should access.
Scenario 41:
You're adding a field for profile pictures in the User model.
Q41. Which field is most suitable for storing profile images?
a) ImageField
b) FileField
c) URLField
d) CharField
Answer: a) ImageField
ImageField validates uploaded files as images, which is ideal for profile pictures.
Scenario 42:
You need to restrict access to the admin dashboard to certain IPs.
Q42. Where would you typically enforce such restrictions?
a) In the model
b) In middleware
c) In views
d) In the settings file
Answer: b) In middleware
Middleware can handle restrictions globally for each request, making it ideal for IP-
based access control.
Scenario 43:
You want to allow users to search by multiple criteria, like name and email, in the admin
panel.
Q43. How should you implement this?
a) Define search_fields in ModelAdmin
b) Add filter_horizontal in ModelAdmin
c) Use list_display in ModelAdmin
d) Use list_filter in ModelAdmin
Answer: a) Define search_fields in ModelAdmin
search_fields allows you to specify fields that the Django admin can search by.
Scenario 44:
You’re implementing pagination for a view.
Q44. Which class can be used to paginate data in a generic view?
a) Paginator
b) Pagination
c) PageView
d) PagingMixin
Answer: a) Paginator
Paginator is Django’s built-in class for splitting data across multiple pages.
Scenario 45:
You need to schedule a daily task to clear temporary files.
Q45. Which approach is most suitable?
a) Define a custom command and use cron
b) Use Django's middleware
c) Implement process_request in views
d) Run a daily loop in the view
Answer: a) Define a custom command and use cron
Defining a custom command with a task scheduler (like cron) is ideal for recurring
tasks.
Scenario 46:
You want to add a method to validate the phone_number field in a form.
Q46. Where should you add this custom validation logic?
a) Inside the form’s __init__ method
b) In the form’s clean_phone_number method
c) In the form’s save method
d) In the model’s __init__ method
Answer: b) In the form’s clean_phone_number method
Custom validation for specific fields should be implemented using clean_ methods
in forms.
Scenario 47:
You’re adding a new URL pattern for viewing individual products.
Q47. What type of path converter would you use to match a product's ID in the URL?
a) int
b) str
c) slug
d) path
Answer: a) int
Using int as a path converter is suitable for IDs, as it expects a whole number.
Scenario 48:
You want to render dynamic data in a template.
Q48. What syntax is used to access the username variable passed to a template?
a) {{ user.username }}
b) {% user.username %}
c) {# user.username #}
d) (( user.username ))
Answer: a) {{ user.username }}
Django templates use double curly braces {{ }} to render variables.
Scenario 49:
You need to define a foreign key relationship in a model for authors of posts.
Q49. Which argument must you include when defining a ForeignKey?
a) related_name
b) on_delete
c) to
d) choices
Answer: b) on_delete
The on_delete argument specifies what to do with related data when the referenced
row is deleted.
Scenario 50:
You want to create an optimized query to count blog posts per category.
Q50. Which ORM method is most efficient for grouping and counting related data?
a) aggregate()
b) annotate()
c) filter()
d) values_list()
Answer: b) annotate()
annotate() can count occurrences of related items, making it ideal for group counts.
Django Scenario-Based MCQs - Practice Questions