django programs
django programs
GenericViews. MIME Types, Generating Non-HTML contents like CSV and PDF, Syndication Feed
Framework, Sitemap framework, Cookies, Sessions, Users and Authentication Using Generic Views
Generic views
Generic views and generic views of objects (class-based views) in Django help simplify and speed up the
development process by providing pre-built views for common tasks. Instead of writing your views
from scratch, you can use these generic views to handle common patterns like displaying a list of objects,
displaying detail pages for a single object, creating new objects, updating existing objects, and deleting
objects.
DRY Principle: They help you adhere to the "Don't Repeat Yourself" principle by eliminating repetitive
code.
Efficiency: They reduce the amount of boilerplate code you need to write, making your codebase cleaner
and more maintainable.
Consistency: They ensure consistency across your views since they follow Django's recommended
practices.
Flexibility: They can be customized to fit specific needs while still providing a solid base functionality.
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post_detail', args=[str(self.id)])
admin.site.register(Post)
4. Define URLs
Edit myapp/urls.py to define the URL patterns.
urlpatterns = [
path('', views.PostListView.as_view(), name='post_list'),
path('post/<int:pk>/', views.PostDetailView.as_view(), name='post_detail'),
path('post/new/', views.PostCreateView.as_view(), name='post_create'),
path('post/<int:pk>/edit/', views.PostUpdateView.as_view(), name='post_edit'),
path('post/<int:pk>/delete/', views.PostDeleteView.as_view(), name='post_delete'),
]
class PostListView(ListView):
model = Post
template_name = 'post_list.html'
class PostDetailView(DetailView):
model = Post
template_name = 'post_detail.html'
class PostCreateView(CreateView):
model = Post
template_name = 'post_form.html'
fields = ['title', 'content']
class PostUpdateView(UpdateView):
model = Post
template_name = 'post_form.html'
fields = ['title', 'content']
class PostDeleteView(DeleteView):
model = Post
template_name = 'post_confirm_delete.html'
success_url = reverse_lazy('post_list')
6. Create Templates
Create templates for the views in myapp/templates/ directory:
post_list.html
<!DOCTYPE html>
<html>
<head>
<title>Post List</title>
</head>
<body>
<h1>Post List</h1>
<ul>
{% for post in object_list %}
<li><a href="{% url 'post_detail' post.pk %}">{{ post.title }}</a></li>
{% endfor %}
</ul>
<a href="{% url 'post_create' %}">Create New Post</a>
</body>
</html>
post_detail.html
<!DOCTYPE html>
<html>
<head>
<title>{{ object.title }}</title>
</head>
<body>
<h1>{{ object.title }}</h1>
<p>{{ object.content }}</p>
<p>Created at: {{ object.created_at }}</p>
<a href="{% url 'post_edit' object.pk %}">Edit</a>
<a href="{% url 'post_delete' object.pk %}">Delete</a>
<a href="{% url 'post_list' %}">Back to list</a>
</body>
</html>
post_form.html
<!DOCTYPE html>
<html>
<head>
<title>{% if object %}Edit Post{% else %}Create Post{% endif %}</title>
</head>
<body>
<h1>{% if object %}Edit Post{% else %}Create Post{% endif %}</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">{% if object %}Update{% else %}Create{% endif %}</button>
</form>
<a href="{% url 'post_list' %}">Back to list</a>
</body>
</html>
post_confirm_delete.html
<!DOCTYPE html>
<html>
<head>
<title>Delete Post</title>
</head>
<body>
<h1>Delete Post</h1>
<p>Are you sure you want to delete "{{ object.title }}"?</p>
<form method="post">
{% csrf_token %}
<button type="submit">Confirm</button>
</form>
<a href="{% url 'post_list' %}">Cancel</a>
</body>
</html>
9. Create a Superuser
Create a superuser to access the Django admin interface:
You should now be able to visit http://127.0.0.1:8000/ and see your app in action, using Django's generic
views to handle listing, creating, updating, and deleting posts.
List of posts
Creating a new Post
Deleting a post
Generic views of objects:
Generic views of objects are pre-built views that handle common patterns for displaying, creating,
updating, and deleting model instances. For the Publisher model, we'll typically want to create views for
listing all publishers, showing details of a specific publisher, creating a new publisher, updating an
existing publisher, and deleting a publisher(All CRUD operations)
pythonCopyINSTALLED_APPS = [
# ...
'publishers',
]
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()
def __str__(self):
return self.name
class Meta:
ordering = ["-name"]
@admin.register(Publisher)
class PublisherAdmin(admin.ModelAdmin):
list_display = ('name', 'city', 'state_province', 'country', 'website')
list_filter = ('country', 'state_province')
search_fields = ('name', 'city')
ordering = ('name',)
fieldsets = (
(None, {
'fields': ('name', 'website')
}),
('Location', {
'fields': ('address', 'city', 'state_province', 'country')
}),
)
fieldsets: Organizes the edit form into two sections for better readability.
Create views in publishers/views.py:
class PublisherListView(ListView):
model = Publisher
template_name = 'publishers/publisher_list.html'
context_object_name = 'publishers'
class PublisherDetailView(DetailView):
model = Publisher
template_name = 'publishers/publisher_detail.html'
class PublisherCreateView(CreateView):
model = Publisher
template_name = 'publishers/publisher_form.html'
fields = ['name', 'address', 'city', 'state_province', 'country', 'website']
success_url = reverse_lazy('publisher_list')
class PublisherUpdateView(UpdateView):
model = Publisher
template_name = 'publishers/publisher_form.html'
fields = ['name', 'address', 'city', 'state_province', 'country', 'website']
success_url = reverse_lazy('publisher_list')
class PublisherDeleteView(DeleteView):
model = Publisher
template_name = 'publishers/publisher_confirm_delete.html'
success_url = reverse_lazy('publisher_list')
def get_queryset(self):
country = self.kwargs.get('country')
return Publisher.objects.filter(country=country)
<h1>Publishers</h1>
<ul>
{% for publisher in publishers %}
<li><a href="{% url 'publisher_detail' publisher.pk %}">{{ publisher.name }}</a></li>
{% endfor %}
</ul>
<a href="{% url 'publisher_create' %}">Create New Publisher</a>
publisher_detail.html:
publisher_form.html:
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Save</button>
</form>
publisher_confirm_delete.html:
<h1>Confirm Delete</h1>
<p>Are you sure you want to delete {{ object.name }}?</p>
<form method="post">
{% csrf_token %}
<button type="submit">Confirm</button>
</form>
<a href="{% url 'publisher_detail' object.pk %}">Cancel</a>
publishers_by_country.html:
Generic views of objects: We've used ListView, DetailView, CreateView, UpdateView, and DeleteView to
handle common CRUD operations for the Publisher model.
Extending Generic views: The PublishersByCountryView extends ListView to provide a custom view
that filters publishers by country. It overrides get_queryset() to filter the queryset and get_context_data()
to add extra context data.
To use this app, include its URLs in your project, myproject’s urls.py:
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('/admin', admin.site.urls),
path('', include('publishers.urls')),
]
This app provides a full set of CRUD operations for the Publisher model using generic views, and
demonstrates how to extend a generic view for custom functionality.
Build an illustrative Django application for returning a reponse from django app in the form of non-html
data such as images,pdf and CSV,zip files and plot and charts
Here is a Django application that demonstrates how to return various types of non-HTML responses,
including images, PDFs, CSV files, ZIP files, and plots/charts. This example will cover different use
cases for each type of response.
Let's start by setting up a basic Django project and then create views for each type of response.
cd non_html_responses
Before getting into VCODE , you have to install these two modules to work in non-html file format
environment .
Update settings.py:
# non_html_responses/settings.py
INSTALLED_APPS = [
# ...
'Myapp',
]
Create views for different response types:
# demo/views.py
# demo/views.py
import csv
import io
import zipfile
from django.http import HttpResponse, FileResponse
from django.shortcuts import render
from reportlab.pdfgen import canvas
from matplotlib import pyplot as plt
import numpy as np
from PIL import Image, ImageDraw
from reportlab.lib import colors
def index(request):
return render(request, 'Myapp/index.html')
def image_response(request):
# Create a simple image using PIL
image = Image.new('RGB', (200, 200), color='yellow')
draw = ImageDraw.Draw(image)
draw.text((40, 70), "FSD", fill='blue')
draw.text((40, 80), "handled by Dr.Sm.Badhusha", fill='blue')
response = HttpResponse(content_type='image/png')
image.save(response, 'PNG')
return response
def pdf_response(request):
# Create a PDF using ReportLab
buffer = io.BytesIO()
p = canvas.Canvas(buffer)
p.setFont("Helvetica-Bold", 36)
p.setFillColor(colors.magenta)
p.drawString(100, 400, "Full Stack Development")
p.setFont("Helvetica-Bold", 18)
p.setFillColor(colors.blue)
p.drawString(100, 375, "Content delivery by Dr.Sm.Badhusha")
p.showPage()
p.save()
buffer.seek(0)
return FileResponse(buffer, as_attachment=True, filename='example.pdf')
def csv_response(request):
# Create a CSV file
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="data.csv"'
writer = csv.writer(response)
writer.writerow(['Name', 'Age', 'Country'])
writer.writerow(['Alice', 28, 'USA'])
writer.writerow(['Bob', 35, 'Canada'])
writer.writerow(['Charlie', 42, 'UK'])
return response
def zip_response(request):
# Create a ZIP file containing multiple files
buffer = io.BytesIO()
with zipfile.ZipFile(buffer, 'w') as zip_file:
zip_file.writestr('file1.txt', 'This is file 1')
zip_file.writestr('file2.txt', 'This is file 2')
buffer.seek(0)
return FileResponse(buffer, as_attachment=True, filename='archive.zip')
def plot_response(request):
# Create a plot using Matplotlib
x = np.linspace(0, 10, 100)
y = np.sin(x)
plt.figure(figsize=(8, 6))
plt.plot(x, y)
plt.title('Sine Wave')
plt.xlabel('x')
plt.ylabel('y')
buffer = io.BytesIO()
plt.savefig(buffer, format='png')
buffer.seek(0)
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.index, name='index'),
path('image/', views.image_response, name='image'),
path('pdf/', views.pdf_response, name='pdf'),
path('csv/', views.csv_response, name='csv'),
path('zip/', views.zip_response, name='zip'),
path('plot/', views.plot_response, name='plot'),
]
Create a simple template to display links to all response types:
<!-- demo/templates/demo/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Non-HTML Responses Demo</title>
</head>
<body>
<h1>Non-HTML Responses Demo</h1>
<ul>
<li><a href="{% url 'image' %}">Image Response</a></li>
<li><a href="{% url 'pdf' %}">PDF Response</a></li>
<li><a href="{% url 'csv' %}">CSV Response</a></li>
<li><a href="{% url 'zip' %}">ZIP Response</a></li>
<li><a href="{% url 'plot' %}">Plot Response</a></li>
</ul>
</body>
</html>
Now you have a Django application that demonstrates various types of non-HTML responses:
Image response: Creates a simple image using PIL and returns it as a PNG file.
PDF response: Generates a PDF file using ReportLab and sends it as an attachment.
CSV response: Creates a CSV file with sample data and sends it as an attachment.
ZIP response: Generates a ZIP file containing multiple files and sends it as an attachment.
Plot response: Creates a Matplotlib plot and returns it as a PNG image.
You can access these responses by visiting the respective URLs or by clicking the links on the index page.
This example covers the basics of returning non-HTML responses in Django. You can expand on this by
adding more complex data processing, error handling, and additional file formats as needed for your
specific use case.
By Clicking Quit
Syndication Feed Framework,
FEED:
A feed, in the context of web content, is a data format used for providing users with frequently
updated content. Feeds allow users to "subscribe" to websites and receive notifications or updates
when new content is published, without having to manually visit the website.
RSS is a specific type of web feed format used to publish frequently updated information such as
blog entries, news headlines, audio, and video. It's a standardized XML-based format.
XML Format: RSS feeds are structured in XML, making them easy for computers to parse.
Standardized: The RSS specification defines a standard way to present information.
Versions: There are several versions of RSS, with RSS 2.0 being widely used.
Content: An RSS document (called a "feed") includes full or summarized text, plus metadata like
publishing date and author.
Content Aggregation: Users can aggregate content from multiple sources in one place.
Time-saving: Users don't need to check websites manually for updates.
Privacy: Users can read content without sharing their email or personal information.
Customization: Readers can choose which content they want to receive.
RSS (Really Simple Syndication) feeds are a standardized format for delivering regularly updated web
content. Here are the main uses of RSS feeds:
1 Content aggregation: Users can subscribe to multiple RSS feeds and view updates from various
websites in one place.
2 Easy content distribution: Publishers can easily distribute their content to subscribers without
relying on email newsletters.
3 Streamlined information consumption: Readers can quickly scan headlines and summaries
without visiting multiple websites.
4 Automatic updates: RSS readers automatically fetch new content, saving users time and effort.
5 Customized news feeds: Users can create personalized news feeds by selecting specific topics or
sources.
6 Improved productivity: Professionals can stay updated on industry news and trends efficiently.
7 Content curation: Bloggers and content creators can easily find and share relevant information.
8 Podcast distribution: Many podcasts use RSS feeds to distribute new episodes to subscribers.
9 SEO benefits: RSS feeds can help improve website visibility and search engine rankings.
Django's Syndication Feed Framework simplifies the process of generating RSS feeds. It handles the
XML generation and allows you to focus on defining what content should be in the feed. When you
create a Feed class in Django (like the LatestPostsFeed in our example), Django automatically generates
the appropriate XML structure for an RSS feed.
When a user or feed reader accesses your feed URL (e.g., http://yourdomain.com/feed/), Django generates
and serves the RSS XML, which can then be interpreted by feed readers or other RSS-compatible
applications.
The Syndication Feed Framework: Django's Syndication Feed Framework is a high-level API that
makes it easy to generate RSS or Atom feeds. It allows you to create feeds from your Django models or
any other data source. The framework takes care of the XML generation, so you can focus on defining
what content should be in the feed.
Key components of the Syndication Feed Framework:
1 Feed class: A subclass of django.contrib.syndication.views.Feed
2 get_object(): Optional method to fetch a specific object (for example, a blog)
3 items(): Method to return a list of items for the feed
4 item_title(), item_description(), item_link(): Methods to define each item's attributes
5 feed_extra_kwargs(): Optional method to add extra elements to the feed
Build a simple blog application with an RSS feed to illustrate the use of the Syndication Feed
Framework.
# feed_demo/settings.py
INSTALLED_APPS = [
# ...
'blog',
]
# blog/models.py
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
pub_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post_detail', args=[str(self.id)])
# blog/views.py
class PostListView(ListView):
model = Post
template_name = 'blog/post_list.html'
context_object_name = 'posts'
ordering = ['-pub_date']
class PostDetailView(DetailView):
model = Post
template_name = 'blog/post_detail.html'
{% block content %}
<h2>Latest Posts</h2>
{% for post in posts %}
<article>
<h3><a href="{% url 'post_detail' post.id %}">{{ post.title }}</a></h3>
<p>{{ post.pub_date }}</p>
</article>
{% endfor %}
{% endblock %}
{% block content %}
<article>
<h2>{{ post.title }}</h2>
<p>{{ post.pub_date }}</p>
<div>{{ post.content }}</div>
</article>
{% endblock %}
# blog/feeds.py
class LatestPostsFeed(Feed):
title = "My Blog Latest Posts"
link = "/feed/"
description = "Latest posts from my blog."
def items(self):
return Post.objects.order_by('-pub_date')[:5]
Set up URLs:
pythonCopy# feed_demo/urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('blog.urls')),
]
# blog/urls.py
urlpatterns = [
path('', PostListView.as_view(), name='post_list'),
path('post/<int:pk>/', PostDetailView.as_view(), name='post_detail'),
path('feed/', LatestPostsFeed(), name='post_feed'),
]
You can now access your blog at http://localhost:8000/ and the RSS feed at http://localhost:8000/feed/.
This example demonstrates:
Build a simple djano APP for explaining practical application for collecting URLs of Indian news
Agents using RSS feeds in website
django-admin startproject rss_reader
cd rss_reader
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('feed_reader.urls'))
]
urlpatterns = [
path('', views.feed_list, name='feed_list'),
]
views.py
import feedparser
from django.shortcuts import render
from django.core.cache import cache
from django.utils import timezone
def fetch_feed(url):
cache_key = f'rss_feed_{url}'
cache_time = 300 # Cache for 5 minutes
# Store in cache
cache.set(cache_key, feed_data, cache_time)
return feed_data
except Exception as e:
print(f"Error fetching feed {url}: {str(e)}")
return None
def feed_list(request):
feed_urls = [
'https://timesofindia.indiatimes.com/rssfeedstopstories.cms',
'https://feeds.feedburner.com/ndtvnews-top-stories',
'https://www.thehindu.com/news/feeder/default.rss',
'https://www.hindustantimes.com/rss/topnews/rssfeed.xml',
'https://indianexpress.com/feed/',
'https://economictimes.indiatimes.com/rssfeedstopstories.cms',
'https://zeenews.india.com/rss/india-national-news.xml',
]
feeds = [feed for feed in (fetch_feed(url) for url in feed_urls) if feed is not None]
context = {
'feeds': feeds,
}
feed_list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RSS Feed Reader</title>
<style>
.feed {
margin-bottom: 30px;
border-bottom: 1px solid #ccc;
padding-bottom: 20px;
}
</style>
</head>
<body>
<h1>RSS Feed Reader</h1>
{% for feed in feeds %}
<div class="feed">
<h2>{{ feed.feed_title }}</h2>
<p>Last updated: {{ feed.last_updated }}</p>
<ul>
{% for entry in feed.feed_entries %}
<li>
<h3><a href="{{ entry.link }}" target="_blank">{{ entry.title }}</a></h3>
<p>{{ entry.summary|safe|truncatewords:30 }}</p>
<small>Published: {{ entry.published }}</small>
</li>
{% endfor %}
</ul>
</div>
{% endfor %}
</body>
</html>
o/p
Sitemap framework
A sitemap is an XML file on your Web site that tells search engine indexers how
frequently your
pages change and how “important” certain pages are in relation to other pages on your
site.
This information helps search engines index your site
A sitemap in Django is a way to provide information about the pages, their relative
importance, and how frequently they are updated on your website. It helps search
engines like Google to crawl your site more efficiently.
A sitemap is a blueprint of your website that help search engines find, crawl and index
all of your website’s content. Sitemaps also tell search engines which pages on your site
are most important.
Normal XML Sitemap: This by far the most common type of sitemap. It’s usually in
the form of an XML Sitemap that links to different pages on your website.
Video Sitemap: Used specifically to help Google understand video content on your
page.
News Sitemap: Helps Google find content on sites that are approved for Google News.
Image Sitemap: Helps Google find all of the images hosted on your site.
Building a practical Django application that demonstrates the use of sitemaps in web-
oriented applications. We'll create a simple blog application with a sitemap to help
search engines index our content effectively.
Build a Django App for creating and maintaining a sitemap and generate some important posts
such as Gold Prices , Oil prices & Silver prices through admin interface and finally generate an
XML file which is accessed by the search engines.
models.py
# sitemap/models.py
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('article_detail', args=[self.slug])
admin.py
admin.site.register(Article)
sitemaps.py
# sitemap/sitemaps.py
class StaticViewSitemap(Sitemap):
priority = 0.5
changefreq = 'daily'
def items(self):
return ['index', 'about', 'contact', 'article_list']
class ArticleSitemap(Sitemap):
changefreq = 'weekly'
priority = 0.8
def items(self):
return Article.objects.all()
def lastmod(self, obj):
return obj.updated_at
urls.py
urlpatterns = [
path('', views.index, name='index'),
path('about/', views.about, name='about'),
path('contact/', views.contact, name='contact'),
path('articles/', views.article_list, name='article_list'),
path('articles/<slug:slug>/', views.article_detail, name='article_detail'),
]
view.py
def index(request):
return render(request, 'sitemap/index.html')
def about(request):
return render(request, 'sitemap/about.html')
def contact(request):
return render(request, 'sitemap/contact.html')
def article_list(request):
articles = Article.objects.all()
return render(request, 'sitemap/article_list.html', {'articles': articles})
settings.py
INSTALLED_APPS = [
....
'django.contrib.sitemaps',
'sitemap',
]
urls.py
# sitemap_explainer/urls.py
sitemaps = {
'static': StaticViewSitemap,
'articles': ArticleSitemap,
}
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('sitemap.urls')),
path('sitemap.xml', sitemap, {'sitemaps': sitemaps}, name='django.contrib.sitemaps.views.sitemap'),
]
Open your browser and navigate to http://127.0.0.1:8000/ to see the sitemap explainer in action,
including dynamically generated article URLs in the sitemap.
Sqlite data which have been added through admin interface
Cookies
Cookies are small pieces of data stored on the client's browser, which can be used to maintain
state information or user preferences across multiple requests.
Browser developers long ago recognized that HTTP’s statelessness poses a huge problem for
Web developers, and thus cookies were born. A cookie is a small piece of information that
browsers store on behalf of Web servers. Every time a browser requests a page from a certain
server, it gives back the cookie that it initially received.
Let’s take a look how this might work. When you open your browser and type in google.com,
your browser sends an HTTP request to Google
Google then can use that Cookie value to know that you’re the same person who accessed
the site earlier. This value might, for example, be a key into a database that stores user information.
Google could (and does) use it to display your name on the page.
HTTP headers are used to pass additional information with HTTP response or HTTP requests. A cookie
is an HTTP request header i.e. used in the requests sent by the user to the server. It contains the cookies
previously sent by the server using one or more set-cookie headers. It is an optional header.
Now, let's build a simple Django app that demonstrates the use of cookies. This app will allow users to
set a preferred theme (light or dark) using cookies.
In cookie_demo/settings.py,
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('theme_preference.urls')),
]
Create theme_preference/urls.py:
urlpatterns = [
path('', views.home, name='home'),
path('set_theme/', views.set_theme, name='set_theme'),
]
Now, let's build a simple Django app that demonstrates the use of cookies. This app will allow users to
set a preferred theme (light or dark) using cookies.
In theme_preference/views.py:
def home(request):
theme = request.COOKIES.get('theme', 'light')
return render(request, 'theme_preference/home.html', {'theme': theme})
def set_theme(request):
if request.method == 'POST':
theme = request.POST.get('theme')
response = redirect('home')
response.set_cookie('theme', theme, max_age=60) # Cookie lasts for 1 minute
return response
return redirect('home')
Create a templates directory in the theme_preference app and add a home.html file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Theme Preference Demo</title>
<style>
body {
font-family: Arial, sans-serif;
transition: background-color 0.3s, color 0.3s;
}
.light {
background-color: powderblue;
color:darkblue;
}
.dark {
background-color: pink;
color: darkred;
}
</style>
</head>
When a user visits the home page, we check for a 'theme' cookie in the request.
If the cookie doesn't exist, we default to the 'light' theme.
The user can change their theme preference using the form.
When the form is submitted, we set a new cookie with the chosen theme.
This example shows how cookies can be used to store user preferences across multiple requests,
creating a personalized experience without requiring user authentication or server-side storage.
When a user visits the home page, we check for a 'theme' cookie in the request.
If the cookie doesn't exist, we default to the 'light' theme.
The user can change their theme preference using the form.
When the form is submitted, we set a new cookie with the chosen theme.
The cookie is set to expire after one year.
On subsequent visits, the app will use the theme stored in the cookie.
This example shows how cookies can be used to store user preferences across multiple requests,
creating a personalized experience without requiring user authentication or server-side storage.
output
Sessions
Session frameworks
This session framework lets you store and retrieve arbitrary data on a per-site-visitor basis. It stores data
on the server side and abstracts the sending and receiving of cookies. Cookies use only a hashed session
ID—not the data itself—thus protecting you from most of the common cookie problems. Let’s look at how
to enable sessions and use them in views.
Sessions in Django:
Sessions are a way to store and retrieve arbitrary data on a per-site-visitor basis. Django abstracts the
process of sending and receiving cookies, letting you work with session data as a Python dictionary on the
server side. Sessions are useful for maintaining user-specific data across multiple requests, such as user
preferences, shopping cart contents, or authentication status.
Key points about Django sessions:
Cookies:
Storage location: Stored on the client-side (user's browser).
Data capacity: Limited (typically 4KB).
Security: Less secure, as data is stored on the client-side and can be viewed/modified by users.
Lifespan: Can be set to expire after a specific time or persist until manually cleared.
Accessibility: Easily accessible by client-side scripts (e.g., JavaScript).
Data type: Can only store string data.
Transmission: Sent with every HTTP request to the server.
Sessions:
Storage location: Primarily stored on the server-side, with only a session ID stored on the client.
Data capacity: Much larger, limited only by server resources. (5mb data)
Security: More secure, as sensitive data is stored on the server and not exposed to the client.
Lifespan: Typically expire after a period of inactivity or when the user logs out.
Accessibility: Not directly accessible by client-side scripts.
Data type: Can store complex data structures and objects.
Transmission: Only the session ID is transmitted between client and server.
Comparison:
6 Security:
6.1 Sessions are generally more secure because the actual data is stored on the server.
6.2 Cookies are less secure as they can be intercepted or manipulated on the client-side.
7 Storage capacity:
7.1 Sessions can store much more data than cookies.
7.2 Cookies are limited in size, making them unsuitable for storing large amounts of data.
8 Performance:
8.1 Cookies can be faster for small amounts of data, as they don't require server-side
lookup.
8.2 Sessions may have a slight performance overhead due to server-side storage and
retrieval.
9 Scalability:
9.1 Cookies scale well as the data is stored on the client-side.
9.2 Sessions may require additional server resources as the number of users increases.
10 Data persistence:
10.1 Cookies can persist for longer periods, even after the browser is closed.
10.2 Sessions typically expire after a shorter period of inactivity.
11 Data complexity:
11.1 Sessions can store complex data structures and objects.
11.2 Cookies are limited to string data.
12 Client-side access:
12.1 Cookie data is easily accessible by client-side scripts.
12.2 Session data is not directly accessible on the client-side.
Use cases:
Cookies are best for:
• Remembering user preferences that don't require high security (e.g., language selection, theme
choices)
• Tracking user behavior for analytics
• Maintaining low-security login states
Sessions are best for:
• Storing sensitive user data (e.g., user ID after login)
• Managing shopping carts in e-commerce applications
• Storing temporary data that requires server-side processing
• Handling complex data structures related to user state
In Django: Django uses a combination of cookies and server-side sessions. It stores a session ID in a
cookie on the client-side, while the actual session data is stored on the server (by default in the database).
This approach combines the benefits of both:
1. Security of server-side storage
2. Ability to store complex data structures
3. Automatic handling of session expiration
4. Easy integration with Django's authentication system
This hybrid approach allows Django to provide a secure and flexible session management system that's
suitable for a wide range of web applications.
cd session_demo
python manage.py startapp preferences
def set_color(request):
if request.method == 'POST':
color = request.POST.get('color')
request.session['preferred_color'] = color
request.session['color_set_time'] = timezone.now().timestamp()
return redirect('display_color')
return render(request, 'set_color.html')
def display_color(request):
current_time = timezone.now().timestamp()
color_set_time = request.session.get('color_set_time', 0)
Step 4: Create templates
Create a directory preferences/templates/ and add two HTML files:
set_color.html:
<!DOCTYPE html>
<html>
<head>
<title>Set Preferred Color</title>
</head>
<body>
<h1>Set Your Preferred Color</h1>
<form method="post">
{% csrf_token %}
<select name="color">
<option value="red">Red</option>
<option value="green">Green</option>
<option value="blue">Blue</option>
</select>
<input type="submit" value="Set Color">
</form>
</body>
</html>
display_color.html:
<!DOCTYPE html>
<html>
<head>
<title>Your Preferred Color</title>
<script>
function updateTimeLeft() {
var timeLeft = {{ time_left|floatformat:0 }};
var countdownElement = document.getElementById('countdown');
if (timeLeft <= 0) {
clearInterval(interval);
location.reload(); // Reload the page when session expires
}
}, 1000);
}
window.onload = updateTimeLeft;
</script>
</head>
<body style="background-color: {{ color }};">
<h1>Your Preferred Color</h1>
<p>Your preferred color is: {{ color }}</p>
<p>Session expires in: <span id="countdown">{{ time_left|floatformat:0 }}</span> seconds</p>
<a href="{% url 'set_color' %}">Change color</a>
</body>
</html>
In session_demo/urls.py:
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('preferences.urls'))
]
In preferences/urls.py:
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.set_color, name='set_color'),
path('display-color/', views.display_color, name='display_color'),
]
This demonstrates how sessions can be used to maintain state for a limited time, and how you can handle
session expiration in both the backend (Django view) and frontend (JavaScript) to provide a seamless user
experience.
Users and Authentication
Authentication in Django is a system that verifies the identity of users and manages user accounts.
It's a crucial part of web applications, allowing you to control access to different parts of your site.
Django provides a built-in authentication system that handles user accounts, groups, permissions,
and cookie-based user sessions.
Here's an explanation of the key components and how to build an app using the template you provided:
1. Authentication in Django:
• User model: Django uses a User model to store user information.
• Authentication backends: These verify credentials and retrieve user information.
• Login and logout views: Django provides views to handle user login and logout.
• Decorators and middleware: These control access to views based on authentication status.
2. Building the App:
Let's create a simple Django app that demonstrates the use of authentication in templates.
Step 1: Set up a new Django project and app
Let's create a Django project called "auth_demo" with an app called "user_auth".
Configure settings:
In user_auth/views.py:
def home(request):
return render(request, 'user_auth/home.html')
def register_view(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user)
return redirect('home')
else:
form = UserCreationForm()
return render(request, 'user_auth/register.html', {'form': form})
def login_view(request):
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
if form.is_valid():
user = form.get_user()
login(request, user)
return redirect('home')
else:
form = AuthenticationForm()
return render(request, 'user_auth/login.html', {'form': form})
@login_required
def logout_view(request):
logout(request)
return redirect('home')
Create templates:
In user_auth/templates/user_auth/home.html:
<!DOCTYPE html>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>Welcome to the Home Page</h1>
{% if user.is_authenticated %}
<p>Hello, {{ user.username }}!</p>
<a href="{% url 'logout' %}">Logout</a>
{% else %}
<p>You are not logged in.</p>
<a href="{% url 'login' %}">Login</a>
<a href="{% url 'register' %}">Register</a>
{% endif %}
</body>
</html>
login.html
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
</head>
<body>
<h2>Login</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Login</button>
</form>
<p>Don't have an account? <a href="{% url 'register' %}">Register here</a></p>
</body>
</html>
logout.html
<!DOCTYPE html>
<html>
<head>
<title>Logged Out</title>
</head>
<body>
<h2>You have been logged out</h2>
<a href="{% url 'login' %}">Login again</a>
</body>
</html>
register.html
<!DOCTYPE html>
<html>
<head>
<title>Register</title>
</head>
<body>
<h2>Register</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Register</button>
</form>
<p>Already have an account? <a href="{% url 'login' %}">Login here</a></p>
</body>
</html>
Set up URLs:
In auth_demo(proj)/urls.py:
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('user_auth.urls')), # This assumes your app is named 'user_auth'
]
urlpatterns = [
path('', views.home, name='home'),
path('register/', views.register_view, name='register'),
path('login/', views.login_view, name='login'),
path('logout/', views.logout_view, name='logout'),
]
If you're not logged in, you'll see a message asking you to log in.
If you're logged in, you'll see your username