0% found this document useful (0 votes)
5 views39 pages

Django Comprehensive Guide

Uploaded by

agfinance27
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views39 pages

Django Comprehensive Guide

Uploaded by

agfinance27
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Django Comprehensive Guide

Unit 2: CRUD Operations using Django


ORM and Migration Process

2.1 Introduction to Django ORM


Django's Object-Relational Mapper (ORM) provides a powerful and intuitive way to interact
with your database using Python code, abstracting away the need to write raw SQL queries.
It acts as a bridge between your Django application's data models and the underlying
database, allowing developers to define database schemas as Python classes and
manipulate data using Python objects 12 12 . This approach simplifies database operations,
enhances code readability, and promotes maintainability.
2.2 Defining Models
In Django, a model is the single, definitive source of information about your data. It's a
Python class that inherits from [Link] and represents a table in your
database. Each attribute of the model class represents a field (column) in the database
table 12 12 .
Here's an example of a simple Product model:
Python
from [Link] import models

class Product([Link]):
name = [Link](max_length=255)
description = [Link](blank=True, null=True)
price = [Link](max_digits=10, decimal_places=2)
stock = [Link](default=0)
created_at = [Link](auto_now_add=True)
updated_at = [Link](auto_now=True)

def __str__(self):
return [Link]

Key Model Field Types:


Field Type Description Example Usage
Stores a small-to-large string. name =
CharField Requires max_length . [Link](max_length=255
)
TextField Stores a large amount of text. description = [Link]()
IntegerField Stores an integer. stock = [Link]()
Stores a fixed-precision price =
DecimalField decimal number. Requires [Link](max_digits=1
max_digits and 0, decimal_places=2)
decimal_places .
is_available =
BooleanField Stores a true/false value. [Link](default=True
)
DateField Stores a date. release_date = [Link]()
created_at =
DateTimeField Stores a date and time. [Link](auto_now_a
dd=True)
category =
ForeignKey A many-to-one relationship. [Link](Category,
on_delete=[Link])

2.3 Database Migrations


Migrations are Django's way of propagating changes you make to your models (adding a
field, deleting a model, etc.) into your database schema 12 . They are essentially a set of
instructions that Django generates to modify your database structure to match your current
models. This system is designed to be robust and handle a wide range of schema changes
12 .
2.3.1 Creating Migrations
After making changes to your [Link] file, you need to create migration files. These files
record the changes and are stored in a migrations directory within your app.
To create migrations, run the following command in your project's root directory:
Bash
python [Link] makemigrations <app_name>

This command inspects your models and creates new migration files (e.g., 0001_initial.py ,
0002_add_new_field.py ) that describe the changes needed to update the database schema.
2.3.2 Applying Migrations
Once migration files are created, you need to apply them to your database. This command
executes the SQL statements defined in the migration files, updating your database schema.
To apply migrations, run:
Bash
python [Link] migrate

This command applies all unapplied migrations for all apps in your project. You can also
specify a particular app to migrate:
Bash
python [Link] migrate <app_name>

2.3.3 Reverting Migrations


In some cases, you might need to revert a migration, for example, to undo a change or to go
back to a previous state of your database schema. You can revert migrations by specifying
the migration name you want to revert to, or by using zero to revert all migrations for an
app.
To revert to a specific migration (e.g., 0001_initial ):
Bash
python [Link] migrate <app_name> 0001_initial

To revert all migrations for a specific app:


Bash
python [Link] migrate <app_name> zero
2.4 CRUD Operations with Django ORM
Django ORM provides a straightforward API for performing Create, Read, Update, and
Delete (CRUD) operations on your database records.
2.4.1 Create (Adding Records)
To create a new record, instantiate a model object and then call its save() method.
Python
from [Link] import Product

# Create a new product


product = Product(name='Laptop', description='Powerful laptop for work and gamin
[Link]()

# Another way to create and save in one step


product = [Link](name='Mouse', description='Wireless ergonomic m

2.4.2 Read (Retrieving Records)


Django ORM provides a Manager (accessed via objects ) for each model to retrieve objects
from the database. QuerySet API allows filtering, ordering, and retrieving data efficiently.
Method Description Example Usage
all() Returns all objects from the all_products =
database. [Link]()
Returns a single object
matching the given lookup
parameters. Raises laptop =
get(**kwargs) DoesNotExist if no object is [Link](name='Laptop'
found, or )
MultipleObjectsReturned if
more than one object is
found.
Returns a new QuerySet expensive_products =
filter(**kwargs) containing objects that match [Link](price__gt=10
the given lookup parameters. 0)
exclude(**kwargs) Returns a new QuerySet in_stock_products =
containing objects that do not [Link](stock=0)
match the given lookup
parameters.
Orders the QuerySet by the products_by_price =
order_by(*fields) given fields. Prefix with - for [Link].order_by('price')
descending order.
Returns the first or last object first_product =
first() / last() in the QuerySet. [Link].order_by('id').first(
)

Field Lookups:
Django's QuerySet API supports various field lookups for advanced filtering:
Lookup Description Example
exact Exact match (case-sensitive). [Link](name__exac
t='Laptop')

iexact Case-insensitive exact match. [Link](name__iexa


ct='laptop')

contains Case-sensitive containment [Link](description_


test. _contains='gaming')

icontains Case-insensitive containment [Link](description_


test. _icontains='gaming')

gt Greater than. [Link](price__gt=10


0)

gte Greater than or equal to. [Link](price__gte=1


00)

lt Less than. [Link](price__lt=50


)

lte Less than or equal to. [Link](price__lte=5


0)

startswith Case-sensitive starts-with. [Link](name__start


swith='Lap')

endswith Case-sensitive ends-with. [Link](name__ends


with='top')
range Range test (inclusive). [Link](price__range
=(20, 50))

isnull IS NULL or IS NOT NULL test. [Link](description_


_isnull=True)

2.4.3 Update (Modifying Records)


To update an existing record, retrieve the object, modify its attributes, and then call its
save() method.
Python
from [Link] import Product

# Retrieve the product


product = [Link](name='Laptop')

# Modify its attributes


[Link] = 1150.00
[Link] = 45

# Save the changes


[Link]()

# Update multiple objects at once (QuerySet update)


[Link](stock__lt=10).update(stock=0)

2.4.4 Delete (Removing Records)


To delete a single record, retrieve the object and call its delete() method.
Python
from [Link] import Product

# Retrieve the product


product = [Link](name='Mouse')

# Delete the product


[Link]()
# Delete multiple objects at once (QuerySet delete)
[Link](stock=0).delete()

2.5 Demonstrating CRUD Operations (Example)


Let's assume we have a Django project named myproject and an app named myapp with
the Product model defined above.
1. Setup (in myapp/[Link] ):
Python
# myapp/[Link]
from [Link] import models

class Product([Link]):
name = [Link](max_length=255)
description = [Link](blank=True, null=True)
price = [Link](max_digits=10, decimal_places=2)
stock = [Link](default=0)
created_at = [Link](auto_now_add=True)
updated_at = [Link](auto_now=True)

def __str__(self):
return [Link]

2. Create Migrations:
Bash
python [Link] makemigrations myapp

3. Apply Migrations:
Bash
python [Link] migrate

4. Interactive Shell Demonstration (using python [Link] shell ):


Python
# Start Django shell
# python [Link] shell
from [Link] import Product

# --- CREATE Operations ---


print("\n--- Creating Products ---")
product1 = [Link](name='Smartphone', description='Latest model s
product2 = [Link](name='Headphones', description='Noise-cancelli
product3 = [Link](name='Smartwatch', description='Fitness tracke
print(f"Created: {product1}")
print(f"Created: {product2}")
print(f"Created: {product3}")

# --- READ Operations ---


print("\n--- Reading Products ---")
# Get all products
all_products = [Link]()
print("All products:")
for p in all_products:
print(f" - {[Link]} (Price: ${[Link]}, Stock: {[Link]})")

# Get a single product by name


try:
smartphone = [Link](name='Smartphone')
print(f"\nFound Smartphone: {[Link]}")
except [Link]:
print("Smartphone not found.")

# Filter products by price greater than 200


expensive_products = [Link](price__gt=200)
print("\nProducts with price > $200:")
for p in expensive_products:
print(f" - {[Link]} (Price: ${[Link]})")

# Filter products with stock less than 200 and order by name
low_stock_products = [Link](stock__lt=200).order_by('name')
print("\nProducts with stock < 200 (ordered by name):")
for p in low_stock_products:
print(f" - {[Link]} (Stock: {[Link]})")

# --- UPDATE Operations ---


print("\n--- Updating Products ---")
# Retrieve a product and update its attributes
headphone = [Link](name='Headphones')
[Link] = 179.99
[Link] = 280
[Link]()
print(f"Updated Headphones: Price to ${[Link]}, Stock to {[Link]

# Update multiple products at once (e.g., increase stock for all products by 10)
[Link]().update(stock=models.F('stock') + 10)
print("\nIncreased stock for all products by 10.")

# Verify updates
all_products = [Link]()
print("All products after update:")
for p in all_products:
print(f" - {[Link]} (Price: ${[Link]}, Stock: {[Link]})")

# --- DELETE Operations ---


print("\n--- Deleting Products ---")
# Delete a single product
smartwatch = [Link](name='Smartwatch')
[Link]()
print(f"Deleted: {[Link]}")

# Delete products with stock less than 50


products_to_delete = [Link](stock__lt=50)
deleted_count, _ = products_to_delete.delete()
print(f"Deleted {deleted_count} products with stock less than 50.")

# Verify deletions
all_products = [Link]()
print("\nAll products after deletion:")
if all_products:
for p in all_products:
print(f" - {[Link]} (Price: ${[Link]}, Stock: {[Link]})")
else:
print("No products remaining.")

References
[1] What is Django ORM? - GeeksforGeeks. GeeksforGeeks. Available at:
[2] Django ORM - Tutorialspoint. Tutorialspoint. Available at:
[3] Models | Django documentation. Django Project. Available at:
[4] Django Models - GeeksforGeeks. GeeksforGeeks. Available at:
[5] Migrations | Django documentation. Django Project. Available at:
[6] Database Migrations in Django - GeeksforGeeks. GeeksforGeeks. Available at:

Unit 3: Static Files, Templates, and


Dynamic Data
3.1 Static Files and Static URL
Django projects often include static files like CSS, JavaScript, and images that are essential
for the front-end of a web application. Django provides a robust mechanism for managing
these static files 12 .
3.1.1 Configuring Static Files
To configure static files, you need to define several settings in your project's [Link] file:
• STATIC_URL : This is the URL prefix for static files. It defines the base URL from which
static files will be served. For example, if STATIC_URL = '/static/' , then a file named
[Link] in your static directory would be accessible at /static/[Link] 12 .
• STATICFILES_DIRS : This is a list of directories where Django will look for static files, in
addition to the static/ subdirectory of each app. These are typically used for project-
wide static assets 12 .
• STATIC_ROOT : This is the absolute path to the directory where collectstatic will gather
all static files for deployment. This directory should not contain any other files and
should not be the same as any of your STATICFILES_DIRS 12 .
Example [Link] configuration:
Python
import os

# ... other settings ...

STATIC_URL = '/static/'

STATICFILES_DIRS = [
[Link](BASE_DIR, 'static'),
]

STATIC_ROOT = [Link](BASE_DIR, 'staticfiles')

3.1.2 Serving Static Files in Development


During development, Django can serve static files automatically. Ensure that
[Link] is included in your INSTALLED_APPS in [Link] . You also need to
add a URL pattern to your project's [Link] to serve static files, especially when DEBUG is
True .
Example [Link] configuration (for development):
Python
from [Link] import admin
from [Link] import path, include
from [Link] import settings
from [Link] import static

urlpatterns = [
path('admin/', [Link]),
# ... other url patterns ...
]

if [Link]:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROO
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT

In your templates, use the {% static 'path/to/your/[Link]' %} template tag to refer to static files.
Remember to load the staticfiles tags at the top of your template: {% load static %} .
3.1.3 Serving Static Files in Production
In a production environment, Django itself should not serve static files. Instead, a dedicated
web server (like Nginx or Apache) should be configured to serve them directly. Before
deploying, you need to collect all static files into the STATIC_ROOT directory using the
collectstatic command:
Bash
python [Link] collectstatic

This command copies all static files from your apps' static/ directories and
STATICFILES_DIRS into the STATIC_ROOT directory. Your web server then serves these files
directly, improving performance and security 12 .
3.2 Validation and Customization (Forms)
Django's form handling framework simplifies the process of creating forms, validating user
input, and rendering forms in templates. It provides robust validation mechanisms at
various levels 12 .
3.2.1 Django Forms Overview
A Django form is defined as a Python class that inherits from [Link] or
[Link] . Each field in the form corresponds to an input element in the HTML
form.
Example [Link] :
Python
from django import forms

class ContactForm([Link]):
name = [Link](max_length=100, label='Your Name')
email = [Link](label='Your Email')
message = [Link](widget=[Link], label='Your Message')

def clean_name(self):
name = self.cleaned_data['name']
if 'badword' in [Link]():
raise [Link]("Name cannot contain 'badword'")
return name

def clean(self):
cleaned_data = super().clean()
email = cleaned_data.get('email')
name = cleaned_data.get('name')

if email and name and [Link]() in [Link]():


self.add_error('email', "Email cannot contain your name.")
return cleaned_data

3.2.2 Field Validation


Django forms perform validation at several stages:
1. Field-level validation: Each field type (e.g., EmailField , IntegerField ) has built-in
validation rules. You can also define custom validation methods for individual fields by
naming them clean_<fieldname> 12 .
2. Form-level validation: The clean() method of the form class allows you to perform
validation that depends on multiple fields. This method should return the cleaned_data
dictionary 12 .
3. Model-level validation: If you are using ModelForm , validation defined in your model
fields (e.g., max_length , unique , validators ) will also be applied.
3.2.3 Customizing Form Widgets
Widgets are Django's representation of an HTML input element. You can customize the
appearance and attributes of form fields by specifying a different widget.
Python
from django import forms

class EnhancedContactForm([Link]):
name = [Link](
max_length=100,
widget=[Link](attrs={'class': 'form-control', 'placeholder': 'E
)
email = [Link](
widget=[Link](attrs={'class': 'form-control', 'required': 'tr
)
message = [Link](
widget=[Link](attrs={'class': 'form-control', 'rows': 5})
)

3.3 Template Tags and Template Filters


Django's template language provides a powerful yet simple way to separate logic from
presentation. It uses template tags and filters to manipulate and display data 12 .
3.3.1 Built-in Template Tags
Template tags are special markers in the template that tell Django's template engine to do
something. They often have a start and end tag, like {% if %} and {% endif %} .
Tag Description Example
for Loops over each item in an {% for item in list %}{{ item }}{%
array or QuerySet. endfor %}

if / elif / else Performs conditional logic. {% if user.is_authenticated %}...{%


else %}...{% endif %}
block / extends Used for template inheritance. See Section 3.4
include Loads a template and renders {% include 'snippets/[Link]'
it with the current context. %}

static Generates the absolute URL {% static 'css/[Link]' %}


of a static file.
Generates a hidden input <form method="post">{%
csrf_token field with the CSRF token for csrf_token %}...</form>
form submissions.
3.3.2 Built-in Template Filters
Template filters transform the value of variables. They are used with the pipe symbol ( | ).
Filter Description Example
upper Converts a string to `{{ value
uppercase.
lower Converts a string to `{{ value
lowercase.
title Converts a string to title case. `{{ value
date Formats a date according to `{{ value
the given format string.
length Returns the length of a value. `{{ list
default If the value is false, uses the `{{ value
given default.
Truncates a string to the
truncatechars specified number of `{{ value
characters.
Marks a string as safe for
safe output (prevents auto- `{{ html_content
escaping).

3.3.3 Custom Template Tags and Filters


Django allows you to create your own custom template tags and filters to extend the
template engine's functionality. This is done by creating a templatetags directory inside
your app, adding an __init__.py file, and then creating a Python module (e.g., my_filters.py )
within it.
Example Custom Filter ( myapp/templatetags/my_filters.py ):
Python
from django import template

register = [Link]()

@[Link]
def multiply(value, arg):
"""Multiplies the value by the argument."""
try:
return float(value) * float(arg)
except (ValueError, TypeError):
return ''

To use this filter in a template, load it first: {% load my_filters %} then {{ some_number|multiply:5
}} .

3.4 Template Inheritance


Template inheritance is a powerful feature in Django that allows you to build a base
template that contains common HTML structure and then extend it in child templates to
add specific content 12 . This promotes code reusability and consistency across your
website.
3.4.1 Basic Inheritance Structure
[Link] (Parent Template):
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}My Site{% endblock %}</title>
{% load static %}
<link rel="stylesheet" href="{% static 'css/[Link]' %}">
{% block extra_head %}{% endblock %}
</head>
<body>
<header>
<h1>{% block header %}Welcome to My Site{% endblock %}</h1>
</header>

<nav>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about/">About</a></li>
<li><a href="/contact/">Contact</a></li>
</ul>
</nav>

<main>
{% block content %}
<p>This is the default content.</p>
{% endblock %}
</main>

<footer>
<p>&copy; 2026 My Site</p>
</footer>

{% block extra_js %}{% endblock %}


</body>
</html>

In [Link] :
• The {% block name %} and {% endblock %} tags define areas that child templates can
override. If a child template doesn't define a block, the content from the parent
template's block is used.
3.4.2 Extending Templates
[Link] (Child Template):
HTML
{% extends '[Link]' %}

{% block title %}Home - My Site{% endblock %}

{% block extra_head %}
<link rel="stylesheet" href="{% static 'css/[Link]' %}">
{% endblock %}

{% block header %}My Awesome Site{% endblock %}

{% block content %}
<h2>Hello from the Homepage!</h2>
<p>This is specific content for the home page.</p>
{% endblock %}

{% block extra_js %}
<script src="{% static 'js/[Link]' %}"></script>
{% endblock %}

In [Link] :
• {% extends '[Link]' %} tells Django that this template inherits from [Link] .
• It then overrides specific blocks defined in [Link] with its own content.
3.5 How to Pass Dynamic Data to Template with Example
Dynamic data is passed from Django views to templates using a context dictionary. The
context is a dictionary-like object that maps variable names to Python objects 12 .
3.5.1 Passing Context from Views
In a Django view, you typically render a template using the render() shortcut, which takes
the request object, the template_name , and a context dictionary as arguments.
Example [Link] :
Python
from [Link] import render
from datetime import datetime

# Assume you have a Product model from Unit 2


from [Link] import Product

def product_list(request):
products = [Link]().order_by("name") # Retrieve all products
current_time = [Link]()
context = {
'products': products,
'page_title': 'Product Catalog',
'current_time': current_time,
'is_admin': True,
}
return render(request, 'myapp/product_list.html', context)

def product_detail(request, product_id):


try:
product = [Link](id=product_id)
except [Link]:
# Handle product not found, e.g., redirect to a 404 page or product lis
product = None # Or raise Http404

context = {
'product': product,
'page_title': [Link] if product else 'Product Not Found',
}
return render(request, 'myapp/product_detail.html', context)
3.5.2 Example: Displaying Dynamic Data
myapp/product_list.html :
HTML
{% extends '[Link]' %}
{% load static %}

{% block title %}{{ page_title }}{% endblock %}

{% block extra_head %}
<link rel="stylesheet" href="{% static 'css/[Link]' %}">
{% endblock %}

{% block header %}{{ page_title }}{% endblock %}

{% block content %}
<h2>Our Products</h2>
<p>Current time: {{ current_time|date:"F j, Y, P" }}</p>

{% if products %}
<div class="product-grid">
{% for product in products %}
<div class="product-card">
<h3><a href="{% url 'product_detail' [Link] %}">{{ prod
<p>{{ [Link]|truncatechars:100 }}</p>
<p><strong>Price: ${{ [Link] }}</strong></p>
<p>Stock: {{ [Link] }}</p>
{% if is_admin %}
<button>Edit Product</button>
{% endif %}
</div>
{% endfor %}
</div>
{% else %}
<p>No products available.</p>
{% endif %}
{% endblock %}

myapp/product_detail.html :
HTML
{% extends '[Link]' %}
{% load static %}

{% block title %}{{ page_title }}{% endblock %}


{% block content %}
{% if product %}
<div class="product-detail">
<h2>{{ [Link] }}</h2>
<p>{{ [Link] }}</p>
<p><strong>Price: ${{ [Link] }}</strong></p>
<p>Stock: {{ [Link] }}</p>
<p>Created: {{ product.created_at|date:"M d, Y" }}</p>
<p>Last Updated: {{ product.updated_at|date:"M d, Y" }}</p>
<a href="/products/">Back to Product List</a>
</div>
{% else %}
<p>The product you are looking for does not exist.</p>
{% endif %}
{% endblock %}

Example [Link] for myapp :


Python
# myapp/[Link]
from [Link] import path
from . import views

urlpatterns = [
path("products/", views.product_list, name="product_list"),
path("products/<int:product_id>/", views.product_detail, name="product_detai
]

References
[7] How to manage static files (e.g. images, JavaScript, CSS). Django Project. Available at:
[7] STATICROOT vs STATICURL in Django. GeeksforGeeks. Available at:
[7] What is the correct settings for static files in django. Stack Overflow. Available at:
[7] Serving Static Files with Django - Joshua Etim - Medium. Medium. Available at:
[7] How to configure static when I want to serve everything ... Reddit. Available at:
[7] Form and field validation - Django documentation. Django Project. Available at:
[7] Django Form Validation - OneUptime. OneUptime. Available at:
[8] Form Validation in Django - GeeksforGeeks. GeeksforGeeks. Available at:
[9] Built-in template tags and filters. Django Project. Available at:
[10] Template inheritance. Django Project. Available at:
[11] The Django template language. Django Project. Available at:
Unit 4: Authentication, REST Framework,
Permissions, Middleware, and Admin

4.1 Explain user authentication in Django


Django provides a full-featured authentication and authorization system that handles user
accounts, groups, permissions, and session management. This system is highly extensible
and integrates seamlessly with other Django components 12 12 .
4.1.1 Built-in Authentication System
The core of Django's authentication system is provided by [Link] . It includes:
• Users: A User model for storing usernames, passwords, email addresses, and other
user-related data.
• Permissions: A way to determine if a user can perform a specific task.
• Groups: A way to apply permissions to a collection of users.
• Password Hashing: Securely stores passwords using configurable hashing algorithms.
• Forms and Views: Built-in forms and views for common authentication tasks like login,
logout, password change, and password reset.
To enable the authentication system, ensure [Link] and
[Link] are in your INSTALLED_APPS in [Link] .
4.1.2 User Model
Django's default User model is located at [Link] . It includes
essential fields such as username , password , email , first_name , last_name , is_active ,
is_staff , and is_superuser . For most projects, the default User model is sufficient. However,
if you need to add custom fields or change authentication behavior, you can extend
Django's AbstractUser or AbstractBaseUser classes 12 .
Extending the User Model (using AbstractUser ):
Python
# myapp/[Link]
from [Link] import AbstractUser
from [Link] import models

class CustomUser(AbstractUser):
# Add any additional fields here
date_of_birth = [Link](null=True, blank=True)
address = [Link](max_length=255, blank=True)

def __str__(self):
return [Link]

Then, in [Link] , tell Django to use your custom user model:


Python
# [Link]
AUTH_USER_MODEL = '[Link]'

4.1.3 Authentication Views and Forms


Django provides a set of pre-built views for common authentication tasks. You can use
them directly or customize them. For example, to include login and logout functionality:
Python
# myproject/[Link]
from [Link] import admin
from [Link] import path, include
from [Link] import views as auth_views

urlpatterns = [
path('admin/', [Link]),
path('login/', auth_views.LoginView.as_view(template_name='registration/logi
path('logout/', auth_views.LogoutView.as_view(next_page='/'), name='logout'
# ... other url patterns ...
]

You would then create a registration/[Link] template to render the login form.
4.2 REST framework in Django API
4.2.1 Introduction to Django REST Framework (DRF)
Django REST Framework (DRF) is a powerful and flexible toolkit for building Web APIs. It
provides a rich set of features that make it easy to create robust and scalable RESTful
services on top of Django 12 12 .
Key features of DRF:
• Serialization: Translates Django models into other data formats (like JSON or XML) and
vice-versa.
• Authentication: Supports various authentication schemes (Token, Session, OAuth,
JWT).
• Permissions: Controls access to API endpoints based on user roles and permissions.
• ViewSets & Routers: Simplifies API development by combining common logic for
related views.
• Browsable API: A user-friendly, web-browsable API for testing and development.
To use DRF, install it ( pip install djangorestframework ) and add 'rest_framework' to your
INSTALLED_APPS in [Link] .
4.2.2 Serializers
Serializers in DRF convert complex data types, such as Django model instances, into native
Python data types that can then be easily rendered into JSON, XML, or other content types.
They also provide deserialization, allowing parsed data to be converted back into complex
types, after first validating the incoming data 12 .
Example myapp/[Link] :
Python
from rest_framework import serializers
from [Link] import Product

class ProductSerializer([Link]):
class Meta:
model = Product
fields = ['id', 'name', 'description', 'price', 'stock']

4.2.3 ViewSets and Routers


ViewSets allow you to combine the logic for a set of related views into a single class.
Routers then automatically generate URL patterns for these ViewSets, reducing boilerplate
code 12 .
Example myapp/[Link] :
Python
from rest_framework import viewsets
from [Link] import Product
from [Link] import ProductSerializer
class ProductViewSet([Link]):
queryset = [Link]()
serializer_class = ProductSerializer

Example myproject/[Link] :
Python
from [Link] import path, include
from rest_framework.routers import DefaultRouter
from [Link] import ProductViewSet

router = DefaultRouter()
[Link](r'products', ProductViewSet)

urlpatterns = [
path('api/', include([Link])),
# ... other url patterns ...
]

4.3 Permission and group in Django


Django's authorization system allows you to control who can do what. This is managed
through permissions and groups 12 .
4.3.1 Permissions System
Permissions are flags that indicate whether a user can perform a certain task. Django
automatically creates three default permissions for each model: add , change , and delete .
You can also define custom permissions in your model's Meta class.
Python
# myapp/[Link]
class Product([Link]):
# ... fields ...

class Meta:
permissions = [
("can_publish_product", "Can publish product"),
("can_view_sales_report", "Can view sales report"),
]

You can check permissions in views or templates:


Python
# In a view
if [Link].has_perm('myapp.can_publish_product'):
# ... allow publishing ...

# In a template
{% if [Link].can_view_sales_report %}
<a href="/sales-report/">View Sales Report</a>
{% endif %}

4.3.2 Groups
Groups are a way to apply permissions to a collection of users. Instead of assigning
permissions to each user individually, you can create a group, assign permissions to that
group, and then add users to the group. Users in a group automatically inherit all
permissions assigned to that group 12 .
Groups can be managed through the Django admin interface or programmatically.
Python
from [Link] import Group, Permission
from [Link] import ContentType
from [Link] import Product

# Create a group
managers_group, created = [Link].get_or_create(name='Managers')

# Get a permission
content_type = [Link].get_for_model(Product)
publish_permission = [Link](codename='can_publish_product', con

# Add permission to the group


managers_group.[Link](publish_permission)

# Add a user to the group


# user = [Link](username='john_doe')
# [Link](managers_group)

4.3.3 Object-level Permissions


While Django's default permission system works at the model level (e.g.,
"can change any product"), sometimes you need object-level permissions (e.g., "can
change this specific product"). Django doesn't have built-in object-level permissions, but
you can implement them using third-party packages like django-guardian or by writing
custom logic in your views or models.
4.4 Step for custom middleware in Django
4.4.1 What is Middleware?
Middleware is a framework of hooks into Django's request/response processing. It's a light,
low-level "plugin" system for globally altering Django's input or output. Each middleware
component is responsible for doing some specific function, such as handling sessions,
authentication, or CSRF protection.
4.4.2 Creating Custom Middleware
To create custom middleware, you define a Python class with specific methods. The most
common approach is to write a class that takes a get_response callable in its __init__
method and implements a __call__ method.
Example myapp/[Link] :
Python
import time

class RequestTimingMiddleware:
def __init__(self, get_response):
self.get_response = get_response
# One-time configuration and initialization.

def __call__(self, request):


# Code to be executed for each request before
# the view (and later middleware) are called.
start_time = [Link]()

response = self.get_response(request)

# Code to be executed for each request/response after


# the view is called.
duration = [Link]() - start_time
print(f"Request to {[Link]} took {duration:.4f} seconds.")

return response

4.4.3 Activating Middleware


To activate your custom middleware, add its dotted path to the MIDDLEWARE list in your
[Link] file. The order of middleware is important, as it determines the order in which
they are executed during the request and response phases.
Python
# [Link]
MIDDLEWARE = [
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'[Link]',
# Add your custom middleware here
'[Link]',
]

4.5 Define Django REST framework


Django REST Framework (DRF) is a powerful, flexible, and widely-used toolkit for building
Web APIs in Django. It simplifies the process of creating RESTful APIs by providing a set of
tools and abstractions that handle common tasks such as serialization, authentication,
permissions, and routing. DRF is designed to be highly customizable, allowing developers
to build APIs that meet their specific requirements while adhering to REST principles. It is
an essential tool for building modern web applications where the backend serves data to
various clients, such as single-page applications (SPAs), mobile apps, or other services.
4.6 Registering model in Django admin
The Django admin site is a built-in, web-based interface that allows authorized users to
manage the data in your application. To make your models accessible and manageable
through the admin interface, you need to register them.
This is done in the [Link] file of your app.
Example myapp/[Link] :
Python
from [Link] import admin
from .models import Product
# Basic registration
# [Link](Product)

# Advanced registration with customization


@[Link](Product)
class ProductAdmin([Link]):
list_display = ('name', 'price', 'stock', 'created_at')
list_filter = ('created_at', 'price')
search_fields = ('name', 'description')
ordering = ('-created_at',)

In this example:
• list_display specifies which fields are displayed as columns on the change list page.
• list_filter adds a sidebar filter based on the specified fields.
• search_fields adds a search box that searches the specified fields.
• ordering specifies the default sorting order.

References
[12] Django Tutorial Part 8: User authentication and permissions. MDN Web Docs. Available
at:
[12] Understanding Django's Authentication System. LinkedIn. Available at:
[12] A comprehensive guide to Django's user authentication system. SuperTokens. Available
at:
[12] Django REST Framework. Django REST Framework. Available at:
[12] User Authentication System using Django. GeeksforGeeks. Available at:
[12] Serializers. Django REST Framework. Available at:
[12] ViewSets. Django REST Framework. Available at:
[12] Working with Role, Permission & Groups in Django. Medium. Available at:
[12] Managing Django groups and permissions for custom users. Stack Overflow. Available
at:

Unit 5: Logging, Debugging, Deployment,


and Advanced Topics

5.1 Logging and Monitoring in Django


Logging is a crucial aspect of any production application, providing insights into its
behavior, performance, and potential issues. Django leverages Python's built-in logging
module, offering a flexible and powerful way to record events 12 .
5.1.1 Django's Logging Configuration
Django's logging is configured within the LOGGING dictionary in [Link] . This dictionary
allows you to define version , disable_existing_loggers , formatters , filters , handlers , and
loggers 12 .
Key Components of Django Logging:
• Loggers: Entry points into the logging system. They are named entities (e.g., django ,
[Link] ) that you use to perform logging operations. Loggers can have a level
(DEBUG, INFO, WARNING, ERROR, CRITICAL) 12 .
• Handlers: Determine where log records go (e.g., console, file, email, database). Each
handler can have its own level and formatter.
• Filters: Provide a way to exert finer-grained control over which log records are passed
from a logger to a handler.
• Formatters: Specify the layout of log records in the final output.
Example [Link] Logging Configuration:
Python
# [Link]
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '{levelname} {asctime} {module} {process:d} {thread:d} {me
'style': '{',
},
'simple': {
'format': '{levelname} {message}',
'style': '{',
},
},
'filters': {
'require_debug_true': {
'()': '[Link]',
},
},
'handlers': {
'console': {
'level': 'INFO',
'filters': ['require_debug_true'],
'class': '[Link]',
'formatter': 'simple'
},
'file': {
'level': 'WARNING',
'class': '[Link]',
'filename': '/var/log/django/[Link]',
'maxBytes': 1024*1024*5, # 5 MB
'backupCount': 5,
'formatter': 'verbose',
},
'mail_admins': {
'level': 'ERROR',
'class': '[Link]',
'formatter': 'verbose',
}
},
'loggers': {
'django': {
'handlers': ['console'],
'propagate': True,
},
'[Link]': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': False,
},
'myapp': { # Custom logger for your app
'handlers': ['console', 'file'],
'level': 'DEBUG',
'propagate': False,
},
'': { # Catch-all logger
'handlers': ['console'],
'level': 'INFO',
}
}
}

Using Loggers in Your Code:


Python
import logging

# Get an instance of a logger


logger = [Link](__name__) # Or [Link]('myapp')

def my_view(request):
[Link]('This is a debug message.')
[Link]('This is an info message.')
[Link]('This is a warning message.')
try:
1 / 0
except ZeroDivisionError:
[Link]('An error occurred during division.')
return HttpResponse("Check your logs!")

5.1.2 Monitoring Tools and Practices


Beyond basic logging, effective monitoring involves tracking application performance, error
rates, and user activity in real-time. Several tools and practices can be employed:
• Application Performance Monitoring (APM) Tools: Services like Sentry, New Relic,
Datadog, and Prometheus provide detailed insights into application health, transaction
tracing, and error tracking 12 12 .
• Log Aggregation: Centralizing logs from multiple sources (e.g., different servers,
microservices) into a single platform (e.g., ELK Stack - Elasticsearch, Logstash, Kibana;
Splunk) makes them easier to search, analyze, and visualize.
• Alerting: Setting up alerts based on log patterns or performance metrics (e.g., high
error rates, slow response times) to notify administrators of critical issues 12 .
• Health Checks: Implementing endpoints that report the health status of your
application and its dependencies.
5.2 Debugging Techniques in Django
Debugging is an essential skill for any developer, helping to identify and resolve issues in
code. Django offers several techniques and tools to aid in the debugging process 12 .
5.2.1 Django Debug Toolbar
The Django Debug Toolbar is a configurable set of panels that display various debugging
information about the current request/response when DEBUG is True . It provides insights
into SQL queries, HTTP headers, settings, signals, and more 12 .
Installation and Setup:
1. Install: pip install django-debug-toolbar
2. Add debug_toolbar to INSTALLED_APPS in [Link] .
3. Add debug_toolbar.[Link] to MIDDLEWARE in [Link] .
4. Configure INTERNAL_IPS in [Link] to include your IP address.
5. Include path('__debug__/', include('debug_toolbar.urls')) in your project's [Link] .
5.2.2 Print Statements and Python Debugger (PDB)
While simple, print() statements can be effective for quickly inspecting variable values at
different points in your code. For more interactive debugging, Python's built-in debugger,
pdb , is invaluable.
To use pdb , insert import pdb; pdb.set_trace() at the point in your code where you want to
start debugging. When the code execution reaches this line, it will pause, and you'll get an
interactive prompt in your terminal, allowing you to inspect variables, step through code,
and execute commands 12 .
5.2.3 IDE Debuggers
Modern Integrated Development Environments (IDEs) like PyCharm, VS Code, or Sublime
Text offer sophisticated debugging tools. These debuggers allow you to set breakpoints,
step through code line by line, inspect the call stack, view and modify variables, and
evaluate expressions. Using an IDE debugger is often the most efficient way to debug
complex issues, as it provides a visual and interactive debugging experience.
5.3 Structure of a Full-Stack Django Web App
A full-stack Django web application typically involves both frontend and backend
components, working together to deliver a complete user experience. While Django is
primarily a backend framework, it can serve static assets and render templates for the
frontend, or it can act as a pure API backend for a separate frontend application (e.g., built
with React, Vue, or Angular).
5.3.1 Frontend Components
When Django handles the frontend, it primarily uses:
• HTML Templates: Rendered by Django's template engine to generate dynamic web
pages.
• CSS: Styles the HTML, often managed with static files.
• JavaScript: Adds interactivity to the web pages, also managed as static files.
• Static Files: Images, fonts, and other assets served directly by the web server.
For more complex frontends, a separate JavaScript framework (like React, Vue, or Angular)
might be used, communicating with Django via its REST API.
5.3.2 Backend Components
The Django backend is responsible for:
• Models: Define the data structure and interact with the database (ORM).
• Views: Handle request/response logic, process data, and render templates or return API
responses.
• URLs: Map URLs to views.
• Forms: Handle user input validation and processing.
• Middleware: Process requests and responses globally.
• Admin: Provides an automatic administrative interface for managing data.
• REST APIs (with DRF): Expose data and functionality to frontend clients or other
services.
5.3.3 Database and APIs
• Database: Django supports various databases (PostgreSQL, MySQL, SQLite, Oracle) and
interacts with them via its ORM.
• APIs: The backend often exposes RESTful APIs (using DRF) to allow the frontend or
other external services to interact with the application's data and logic. This separation
allows for a decoupled architecture, where frontend and backend can be developed
and scaled independently.
5.4 Steps for Project Deployment
Deploying a Django application involves moving it from a development environment to a
production server, making it accessible to users. This typically includes several key steps 12 .
5.4.1 Pre-deployment Checklist
Before deploying, ensure the following:
• DEBUG = False : Set DEBUG to False in [Link] for security and performance.
• ALLOWED_HOSTS : Configure ALLOWED_HOSTS in [Link] with the domain names
that your Django site will serve.
• Static and Media Files: Run python [Link] collectstatic to gather all static files.
Configure your web server to serve static and media files efficiently.
• Database Configuration: Use a robust production-ready database (e.g., PostgreSQL)
and ensure its connection settings are correct.
• Secret Key: Ensure your SECRET_KEY is strong and kept secret, ideally loaded from an
environment variable.
• Environment Variables: Use environment variables for sensitive information (database
credentials, API keys) instead of hardcoding them.
• HTTPS: Configure HTTPS for secure communication.
• Backup Strategy: Implement a strategy for backing up your database and media files.
5.4.2 Gunicorn and Nginx
A common and robust deployment setup for Django applications involves a combination of:
• Gunicorn (Green Unicorn): A Python WSGI HTTP Server for UNIX. It acts as an
application server, running your Django application and handling requests from the
web server 12 .
• Nginx: A high-performance web server that acts as a reverse proxy. It handles incoming
client requests, serves static and media files directly, and forwards dynamic requests to
Gunicorn 12 .
Basic Flow:
Client Request -> Nginx -> Gunicorn -> Django Application -> Database
5.5 Deploy Django Application on Heroku and AWS
5.5.1 Deployment on Heroku
Heroku is a cloud Platform-as-a-Service (PaaS) that makes deploying Django applications
relatively straightforward. It handles much of the infrastructure management, allowing
developers to focus on their code.
Key Steps for Heroku Deployment:
1. Procfile: Create a Procfile in your project root to tell Heroku how to run your
application (e.g., web: gunicorn [Link] ).
2. [Link] : Generate a [Link] file ( pip freeze > [Link] ) to list all
project dependencies.
3. [Link] : Specify the Python version (e.g., python-3.11.0 ).
4. [Link] adjustments: Configure DATABASE_URL (Heroku provides PostgreSQL),
ALLOWED_HOSTS , and static file serving (e.g., using whitenoise ).
5. Git and Heroku CLI: Initialize a Git repository and use the Heroku CLI to create an app
and push your code.
5.5.2 Deployment on AWS (EC2 with Gunicorn/Nginx)
Deploying on Amazon Web Services (AWS) Elastic Compute Cloud (EC2) provides more
control and flexibility but requires more manual configuration. A typical setup involves an
EC2 instance running a Linux distribution, Gunicorn, and Nginx.
Key Steps:
1. Launch EC2 Instance: Choose an appropriate instance type and AMI (e.g., Ubuntu
Server).
2. Security Group Configuration: Open necessary ports (e.g., 22 for SSH, 80 for HTTP, 443
for HTTPS).
3. SSH into Instance: Connect to your EC2 instance using SSH.
4. Install Dependencies: Install Python, pip, virtualenv, Nginx, and other system
dependencies.
5. Clone Repository: Clone your Django project from a version control system (e.g., Git).
6. Virtual Environment: Create and activate a Python virtual environment.
7. Install Python Dependencies: pip install -r [Link] .
8. Database Setup: Configure and connect to a database (e.g., PostgreSQL on RDS or on
the EC2 instance).
9. Gunicorn Configuration: Create a Gunicorn systemd service file to run your Django
application.
[Link] Configuration: Configure Nginx as a reverse proxy to forward requests to
Gunicorn and serve static/media files.
[Link] Static Files: python [Link] collectstatic .
[Link] with Certbot: Secure your site with SSL/TLS using Certbot for Nginx.
5.6 Steps to Integrate Authentication Database REST API
Integrating an authentication database with a REST API typically involves using Django's
built-in authentication system in conjunction with Django REST Framework (DRF) for API
endpoints.
5.6.1 Using Django REST Framework for Authentication
DRF provides various authentication classes that can be used with your API views:
• TokenAuthentication : A simple token-based authentication scheme. Users obtain a
unique token (e.g., upon login) and include it in the Authorization header of subsequent
API requests.
• SessionAuthentication : Suitable for clients that maintain a session (e.g., browser-based
applications that log in via Django's session system).
• BasicAuthentication : Uses HTTP Basic Authentication, sending username and password
with each request (less secure for production without HTTPS).
• JSONWebTokenAuthentication (third-party): For JWT-based authentication, often used
in single-page applications.
Example [Link] (for Token Authentication):
Python
# [Link]
INSTALLED_APPS = [
# ...
'rest_framework',
'rest_framework.authtoken', # For TokenAuthentication
# ...
]

REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.[Link]',
'rest_framework.[Link]',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.[Link]',
]
}

Example myapp/[Link] (API View with Authentication):


Python
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework.[Link] import ObtainAuthToken
from rest_framework.[Link] import Token
from rest_framework.settings import api_settings

class HelloView(APIView):
permission_classes = (IsAuthenticated,)
def get(self, request):
content = {
'message': f'Hello, {[Link]}! You are authenticated.
'user_id': [Link]
}
return Response(content)

class CustomAuthToken(ObtainAuthToken):
def post(self, request, *args, **kwargs):
serializer = self.serializer_class(data=[Link],
context={'request': request})
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
token, created = [Link].get_or_create(user=user)
return Response({
'token': [Link],
'user_id': [Link],
'email': [Link]
})

# In [Link]:
# path('api/hello/', HelloView.as_view(), name='hello_api'),
# path('api/auth/', CustomAuthToken.as_view(), name='api_auth_token'),

5.6.2 Integrating with Frontend


When using a separate frontend (e.g., a React app), the integration typically involves:
1. Login Request: The frontend sends a POST request to your DRF authentication
endpoint (e.g., /api/auth/ ) with username and password.
2. Token Reception: The backend authenticates the user and returns an authentication
token (e.g., JWT or DRF Token).
3. Token Storage: The frontend stores this token (e.g., in localStorage or sessionStorage ).
4. Authenticated Requests: For subsequent requests to protected API endpoints, the
frontend includes the token in the Authorization header (e.g., Authorization: Token
<your_token> or Authorization: Bearer <your_jwt> ).

5.7 Define Django Admin and How to Customize


5.7.1 Django Admin Overview
The Django admin is an automatically generated administrative interface for your Django
models. It's a powerful tool that allows non-technical users (or developers during
development) to create, read, update, and delete (CRUD) data in your application without
writing any code. It's built by introspecting your models and provides a user-friendly
interface for managing your application's content 13 .
Key features include:
• Automatic Interface: Generates a UI based on your models.
• Authentication & Authorization: Integrates with Django's auth system to control who
can access and modify data.
• CRUD Operations: Provides forms for adding, editing, and deleting model instances.
• Search & Filtering: Built-in capabilities to search and filter records.
• Customization: Highly customizable to fit specific needs.
5.7.2 Customizing the Admin Interface
While the default admin interface is functional, Django provides extensive options for
customization to improve usability and tailor it to your application's requirements.
Customization is primarily done by creating ModelAdmin classes in your app's [Link] file.
Common Customizations:
• list_display : Controls which fields are displayed as columns on the change list page.
• list_filter : Adds filters to the right sidebar, allowing users to quickly narrow down the
list of objects.
• search_fields : Adds a search box to the change list page, enabling searching across
specified fields.
• ordering : Defines the default sorting order for the change list.
• fieldsets : Organizes fields into groups on the add/change form for better readability.
• raw_id_fields : Changes an ForeignKey or ManyToManyField widget to an Input widget,
useful for models with many related objects.
• readonly_fields : Specifies fields that are displayed but not editable on the add/change
form.
• inlines : Allows editing of related objects on the same page as the parent object (e.g.,
editing LineItem s directly from an Order page).
• Custom Admin Actions: Add custom actions to the admin's action dropdown menu.
• Custom Templates: Override default admin templates for more extensive visual
changes.
Example myapp/[Link] (Advanced Customization):
Python
from [Link] import admin
from .models import Product, Category # Assuming a Category model exists

# Register Category model


@[Link](Category)
class CategoryAdmin([Link]):
list_display = ('name', 'description')
search_fields = ('name',)

# Define an inline for Product if Category has many products


class ProductInline([Link]):
model = Product
extra = 1 # How many empty forms to display

@[Link](Product)
class ProductAdmin([Link]):
list_display = ('name', 'category', 'price', 'stock', 'is_available', 'crea
list_filter = ('is_available', 'category', 'created_at')
search_fields = ('name', 'description')
date_hierarchy = 'created_at' # Adds a date-based drilldown navigation
ordering = ('-created_at', 'name')
raw_id_fields = ('category',) # Use raw ID input for category

fieldsets = (
(None, {
'fields': (('name', 'category'), 'description')
}),
('Pricing & Stock', {
'fields': (('price', 'stock'), 'is_available'),
'classes': ('collapse',)
}),
('Timestamps', {
'fields': ('created_at', 'updated_at'),
'classes': ('collapse',),
'description': 'Automatically managed timestamps'
}),
)
readonly_fields = ('created_at', 'updated_at')

# Custom admin action


def make_unavailable(self, request, queryset):
[Link](is_available=False)
make_unavailable.short_description = "Mark selected products as unavailable

actions = [make_unavailable]

# Example of overriding a formfield


def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "category":
kwargs["queryset"] = [Link](is_active=True) # Only
return super().formfield_for_foreignkey(db_field, request, **kwargs)

References
[12] Logging | Django documentation. Django Project. Available at:
[12] How to configure and use logging - Django documentation. Django Project. Available at:
[12] The Complete Guide to Logging in Django - DEV Community. DEV Community. Available
at:
[12] Real-time Monitoring in Django: Essential Tools and Techniques. LaunchDarkly.
Available at:
[12] Mastering Django Application Monitoring: From Performance Metrics ... Medium.
Available at:
[12] Monitoring - Django Packages. Django Packages. Available at:
[12] Debugging a Django Application. GeeksforGeeks. Available at:
[12] Mastering Django debugging: a complete guide. Aubergine Solutions. Available at:
[12] How I Debug Django Without Losing My Mind. Medium. Available at:
[12] Deploying Django. Django Project. Available at:
[12] Gunicorn. Gunicorn. Available at:
[12] Nginx. Nginx. Available at:
[13] The Django admin site. Django Project. Available at:

You might also like