0% found this document useful (0 votes)
11 views

django programs

Uploaded by

Ebenezer Mathew
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views

django programs

Uploaded by

Ebenezer Mathew
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 53

Using Generic Views, Generic Views of Objects, Extending Generic Views of objects, Extending

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.

Role of Generic Views

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.

Common Generic Views

ListView: Display a list of objects.


DetailView: Display a single object.
CreateView: Display a form for creating a new object and handle the object creation.
UpdateView: Display a form for updating an existing object and handle the update.
DeleteView: Display a confirmation page and handle the deletion of an object.

Building a Simple Django App Using Generic Views

1. Setup Your Django Project and App


First, create a Django project and an app.
django-admin startproject myproject
cd myproject
django-admin startapp myapp

2. Define Your Models


Edit myapp/models.py to define a simple model, such as Post.

from django.db import models


from django.urls import reverse
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
created_at = 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)])

3. Register the Model in Admin


Edit myapp/admin.py to register the Post model.

from django.contrib import admin


from .models import Post

admin.site.register(Post)

4. Define URLs
Edit myapp/urls.py to define the URL patterns.

from django.urls import path


from . import views

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'),
]

5. Create Views Using Generic Views


Edit myapp/views.py to create views using generic views.

from django.urls import reverse_lazy


from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from .models import Post

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>

7. Configure URL Patterns


Edit myproject/urls.py to include the app's URLs.

from django.contrib import admin


from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('myapp.urls')),
]

8. Create and Apply Migrations


Run the following commands to create and apply the migrations:

python manage.py makemigrations


python manage.py migrate

9. Create a Superuser
Create a superuser to access the Django admin interface:

python manage.py createsuperuser

10. Run the Server


Finally, run the Django development server:

python manage.py runserver

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

Selecting a Post ( Edit or Delete can be performed)


Editing a 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)

Extending Generic views:


Extending generic views allows you to customize their behavior by overriding methods or adding new
functionality. This is done by subclassing the generic view and modifying its attributes or methods.

Now, let's build a Django app to illustrate these concepts:

Create a new Django app:

python manage.py startapp publishers

Add the app to INSTALLED_APPS in your project's settings.py:

pythonCopyINSTALLED_APPS = [
# ...
'publishers',
]

Define the model in publishers/models.py:

from django.db import models

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"]

Create or modify the file publishers/admin.py:

from django.contrib import admin


from .models import Publisher

@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')
}),
)

This admin configuration does the following:

list_display: Specifies which fields to display in the list view of publishers.


list_filter: Adds filters for country and state/province in the right sidebar.
search_fields: Enables searching by name and city.
ordering: Sets the default ordering to be by name.
fieldsets: Organizes the edit form into two sections for better readability.

To use this admin interface:

Make sure you have created a superuser account:


python manage.py createsuperuser

fieldsets: Organizes the edit form into two sections for better readability.
Create views in publishers/views.py:

from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView


from django.urls import reverse_lazy
from .models import Publisher

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')

# Example of extending a generic view


class PublishersByCountryView(ListView):
model = Publisher
template_name = 'publishers/publishers_by_country.html'
context_object_name = 'publishers'

def get_queryset(self):
country = self.kwargs.get('country')
return Publisher.objects.filter(country=country)

def get_context_data(self, **kwargs):


context = super().get_context_data(**kwargs)
context['country'] = self.kwargs.get('country')
return context

Create URLs in publishers/urls.py(App url):


from django.urls import path
from . import views
urlpatterns = [
path('', views.PublisherListView.as_view(), name='publisher_list'),
path('<int:pk>/', views.PublisherDetailView.as_view(), name='publisher_detail'),
path('create/', views.PublisherCreateView.as_view(), name='publisher_create'),
path('<int:pk>/update/', views.PublisherUpdateView.as_view(), name='publisher_update'),
path('<int:pk>/delete/', views.PublisherDeleteView.as_view(), name='publisher_delete'),
path('country/<str:country>/', views.PublishersByCountryView.as_view(),
name='publishers_by_country'),
]
Create templates in publishers/templates/publishers/:
publisher_list.html:

<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:

<h1>{{ publisher.name }}</h1>


<p>Address: {{ publisher.address }}</p>
<p>City: {{ publisher.city }}</p>
<p>State/Province: {{ publisher.state_province }}</p>
<p>Country: {{ publisher.country }}</p>
<p>Website: <a href="{{ publisher.website }}">{{ publisher.website }}</a></p>
<a href="{% url 'publisher_update' publisher.pk %}">Update</a>
<a href="{% url 'publisher_delete' publisher.pk %}">Delete</a>
<a href="{% url 'publisher_list' %}">Back to List</a>

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:

<h1>Publishers in {{ country }}</h1>


<ul>
{% for publisher in publishers %}
<li><a href="{% url 'publisher_detail' publisher.pk %}">{{ publisher.name }}</a></li>
{% endfor %}
</ul>
<a href="{% url 'publisher_list' %}">Back to All Publishers</a>
This example illustrates both concepts:

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.

Creating New Publisher


Viewing a particular publisher

Editing a particular publisher

Deleting a particular publisher


Generating Non-HTML contents like CSV and PDF

Development of Dynamic Files and Visualizations in Django

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.

Set up the Django project:

django-admin startproject Non_Html_Responses

cd non_html_responses

python manage.py startapp Myapp

Before getting into VCODE , you have to install these two modules to work in non-html file format
environment .

pip install reportlab==3.6.1


pip install matplotlib

Update settings.py:

# non_html_responses/settings.py

INSTALLED_APPS = [
# ...
'Myapp',
]
Create views for different response types:

# demo/views.py

from django.shortcuts import render

# Create your views here.

# 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)

return FileResponse(buffer, content_type='image/png')

Create URL patterns:


# non_html_responses/urls.py

from django.contrib import admin


from django.urls import path
from demo import views

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>

Install required dependencies:


pip install django reportlab matplotlib pillow

Run the development server:


python manage.py runserver

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.

INPUT AND OUTPUT


By Clicking Image Response

By Clicking PDF Response

By Clicking CSV Response


By Clicking ZIP Response

By Clicking Plot Response

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.

Key points about feeds:

 They provide a summary of a website's recently added content.


 They're typically machine-readable, designed for computers to parse easily.
 They enable content syndication, allowing websites to share content automatically.
 Common feed formats include RSS and Atom.

RSS (Really Simple Syndication):

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.

Key features of RSS:

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.

Structure of an RSS feed:

<?xml version="1.0" encoding="UTF-8" ?>


<rss version="2.0">
<channel>
<title>Feed Title</title>
<link>http://www.example.com/</link>
<description>This is an example RSS feed</description>
<item>
<title>Entry Title</title>
<link>http://www.example.com/entry1</link>
<description>Here is some text containing a description.</description>
<pubDate>Mon, 06 Sep 2021 16:45:00 +0000</pubDate>
</item>
<!-- More items can follow -->
</channel>
</rss>
Benefits of using RSS:

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.

In the context of Django:

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.

The framework allows you to:

 Define feed metadata (title, link, description)


 Specify which items should be included in the feed
 Determine how each item in the feed should be represented

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.

Set up a new Django project and app:

django-admin startproject feed_demo


cd feed_demo
python manage.py startapp blog

Add 'blog' to INSTALLED_APPS in settings.py:

# feed_demo/settings.py

INSTALLED_APPS = [
# ...
'blog',
]

Create a simple blog model:

# blog/models.py

from django.db import models


from django.urls import reverse

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)])

Create views for the blog:

# blog/views.py

from django.views.generic import ListView, DetailView


from .models import Post

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'

Create templates for the blog:

<!-- blog/templates/blog/base.html -->


<!DOCTYPE html>
<html>
<head>
<title>{% block title %}My Blog{% endblock %}</title>
</head>
<body>
<header>
<h1>My Blog</h1>
<a href="{% url 'post_list' %}">Home</a>
<a href="{% url 'post_feed' %}">RSS Feed</a>
</header>
<main>
{% block content %}
{% endblock %}
</main>
</body>
</html>

<!-- blog/templates/blog/post_list.html -->


{% extends 'blog/base.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 %}

<!-- blog/templates/blog/post_detail.html -->


{% extends 'blog/base.html' %}

{% block content %}
<article>
<h2>{{ post.title }}</h2>
<p>{{ post.pub_date }}</p>
<div>{{ post.content }}</div>
</article>
{% endblock %}

Create the feed class:

# blog/feeds.py

from django.contrib.syndication.views import Feed


from django.urls import reverse
from .models import Post

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]

def item_title(self, item):


return item.title

def item_description(self, item):


return item.content[:100] + '...'

def item_link(self, item):


return reverse('post_detail', args=[item.pk])

def item_pubdate(self, item):


return item.pub_date

Set up URLs:
pythonCopy# feed_demo/urls.py

from django.contrib import admin


from django.urls import path, include

urlpatterns = [
path('admin/', admin.site.urls),
path('', include('blog.urls')),
]

# blog/urls.py

from django.urls import path


from .views import PostListView, PostDetailView
from .feeds import LatestPostsFeed

urlpatterns = [
path('', PostListView.as_view(), name='post_list'),
path('post/<int:pk>/', PostDetailView.as_view(), name='post_detail'),
path('feed/', LatestPostsFeed(), name='post_feed'),
]

Run migrations and create some sample data:

python manage.py makemigrations


python manage.py migrate

python manage.py createsuperuser


Now, start the development server and create some blog posts through the admin interface:

python manage.py runserver


Visit http://localhost:8000/admin/ to add some posts.

You can now access your blog at http://localhost:8000/ and the RSS feed at http://localhost:8000/feed/.
This example demonstrates:

Creating a basic blog application


Implementing an RSS feed using Django's Syndication Feed Framework
Customizing feed content and metadata
o/p

Home page of the blog

Admin Interface of the Blog post

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

python manage.py startapp feed_reader

project rss_reader URL

from django.contrib import admin


from django.urls import path,include

urlpatterns = [
path('admin/', admin.site.urls),
path('',include('feed_reader.urls'))
]

App feed_reader URL

from django.urls import path


from . import views

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

# Try to get the feed from cache


cached_feed = cache.get(cache_key)
if cached_feed is not None:
return cached_feed

# If not in cache, fetch the feed


try:
feed = feedparser.parse(url)
feed_data = {
'feed_title': feed.feed.get('title', 'Unknown Feed'),
'feed_entries': [],
'last_updated': timezone.now(),
}

for entry in feed.entries[:5]: # Display the first 5 entries


feed_data['feed_entries'].append({
'title': entry.get('title', 'No title'),
'link': entry.get('link', '#'),
'summary': entry.get('summary', 'No summary available'),
'published': entry.get('published', 'No date available')
})

# 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,
}

return render(request, 'feed_reader/feed_list.html', context)

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.

There are four main types of sitemaps:

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.

Modules in sitemap App

models.py

# sitemap/models.py

from django.db import models


from django.urls import reverse
class Article(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
slug = models.SlugField(unique=True)
updated_at = models.DateTimeField(auto_now=True)

def __str__(self):
return self.title

def get_absolute_url(self):
return reverse('article_detail', args=[self.slug])

admin.py

from django.contrib import admin

# Register your models here.


from django.contrib import admin
from .models import Article

admin.site.register(Article)

sitemaps.py

# sitemap/sitemaps.py

from django.contrib.sitemaps import Sitemap


from django.urls import reverse
from .models import Article

class StaticViewSitemap(Sitemap):
priority = 0.5
changefreq = 'daily'

def items(self):
return ['index', 'about', 'contact', 'article_list']

def location(self, item):


return reverse(item)

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

from django.urls import path


from . import views

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

from django.shortcuts import render, get_object_or_404


from .models import Article

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})

def article_detail(request, slug):


article = get_object_or_404(Article, slug=slug)
return render(request, 'sitemap/article_detail.html', {'article': article})

Modules in the SiteMap_Explainer Project

settings.py

INSTALLED_APPS = [
....
'django.contrib.sitemaps',
'sitemap',
]

urls.py

# sitemap_explainer/urls.py

from django.contrib import admin


from django.urls import path, include
from django.contrib.sitemaps.views import sitemap
from sitemap.sitemaps import StaticViewSitemap, ArticleSitemap

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'),
]

To access admin interface

python manage.py createsuperuser

To make migrations and execute server

python manage.py makemigrations


python manage.py migrate
python manage.py runserver

Create Some Articles (through admin interface)


Access the Django admin at http://127.0.0.1:8000/admin/ to create some articles.
To Access the Application:

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

To Access XML file


Open your browser and navigate to http://127.0.0.1:8000/sitemap.xml to see the xml file which is to
be accessed by search engines
Cookies

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.

Here's a brief overview of cookies from Django's perspective:

 Django provides easy-to-use methods for setting and getting cookies.


 Cookies can be set on the HttpResponse object.
 Incoming cookies can be accessed via the request.COOKIES dictionary.
 Django's session framework uses cookies to store a session ID, with the actual session data
stored on the server side.

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.

First, let's set up a new Django project and app:

django-admin startproject cookie_demo


cd cookie_demo

django-admin startapp theme_preference

Now, let's modify the necessary files:

In cookie_demo/settings.py,

add 'theme_preference' to INSTALLED_APPS.


In cookie_demo/urls.py:

from django.contrib import admin


from django.urls import path, include

urlpatterns = [
path('admin/', admin.site.urls),
path('', include('theme_preference.urls')),
]

Create theme_preference/urls.py:

from django.urls import path


from . import views

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:

from django.shortcuts import render

# Create your views here.

from django.shortcuts import render, redirect


from django.http import HttpResponse

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>

<body class="{{ theme }}">


<h1>Theme Preference Demo</h1>
<p>Current theme: {{ theme }}</p>
<form action="{% url 'set_theme' %}" method="post">
{% csrf_token %}
<label>
<input type="radio" name="theme" value="light" {% if theme == 'light' %}checked{% endif
%}> Normal Mode
</label>
<label>
<input type="radio" name="theme" value="dark" {% if theme == 'dark' %}checked{% endif
%}>Cookie Set Mode
</label>
<h1> Normal Set is default mode ( i.e Cookie not set) </h1>
<h1> If you want to set cookie for a minute press Cookie set and wait for a minute for expiry of
Cookie</h1>
<button type="submit">Set Theme</button>
</form>
</body>
</html>

Finally, run migrations and start the development server:

python manage.py migrate


python manage.py runserver
This app demonstrates the use of cookies in Django:

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 minute


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.

Finally, run migrations and start the development server:

python manage.py migrate


python manage.py runserver
This app demonstrates the use of cookies in Django:

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:

By default, Django stores sessions in the database.


Sessions are enabled by default in Django projects.
Each session is associated with a unique session ID.
Session data is stored server-side, with only the session ID passed to the client.

Comparison of Cookies with 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.

Now, let's build a simple app to demonstrate sessions in Django.


Practical App: User Preferences
We'll create a web app where users can set their preferred theme color, which will be remembered across
requests using sessions.

Explain sessions in django .


Build an practical app to illustrate the role oof session in django application

Step 1: Set up a new Django project and app


django-admin startproject session_demo

cd session_demo
python manage.py startapp preferences

Step 2: Configure the project


In session_demo/settings.py, add 'preferences' to INSTALLED_APPS:
INSTALLED_APPS = [
# ...
'preferences',
]

Step 3: Create views


In preferences/views.py:

from django.shortcuts import render, redirect


from django.utils import timezone

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');

var interval = setInterval(function() {


timeLeft--;
countdownElement.textContent = timeLeft;

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>

Step 5: Set up URLs

In session_demo/urls.py:

from django.contrib import admin


from django.urls import path,include

urlpatterns = [
path('admin/', admin.site.urls),
path('',include('preferences.urls'))
]

In preferences/urls.py:

from django.contrib import admin


from django.urls import path
from preferences import views

urlpatterns = [
path('admin/', admin.site.urls),
path('', views.set_color, name='set_color'),
path('display-color/', views.display_color, name='display_color'),
]

Step 6: Run migrations and start the server


python manage.py migrate
python manage.py runserver
Now, visit http://localhost:8000/set-color/ to set a preferred color, and http://localhost:8000/display-color/
to see it in action.

This app demonstrates the role of sessions in Django:

 Stores the timestamp when the color is set.


 Checks if the session has expired (more than 30 seconds since the color was set) in the
display_color view.
 Uses JavaScript to create a countdown timer and automatically reload the page when the session
expires.
 Displays the time left before the session expires.
When the session expires:

The background will change to white (the default color).


The page will automatically reload to reflect this change.

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".

Set up the project:

django-admin startproject auth_demo


cd auth_demo
python manage.py startapp user_auth

Configure settings:

In auth_demo/settings.py, add 'user_auth' to INSTALLED_APPS:


pythonCopyINSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'user_auth',
]
LOGIN_REDIRECT_URL = 'home'
LOGIN_URL = 'login'
Create views:

In user_auth/views.py:

from django.shortcuts import render, redirect


from django.contrib.auth import login, authenticate, logout
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.contrib.auth.decorators import login_required

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:

Create a directory: user_auth/templates/user_auth/

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:

from django.contrib import admin


from django.urls import path, include

urlpatterns = [
path('admin/', admin.site.urls),
path('', include('user_auth.urls')), # This assumes your app is named 'user_auth'
]

Create a new file user_auth(app)/urls.py:

from django.urls import path


from . import views

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'),
]

Create and apply migrations:

python manage.py makemigrations


python manage.py migrate
Run the server:

python manage.py runserver


Now, your Django app is set up and running. Here's what you can do:

Visit http://localhost:8000/ to see the home page.

This app demonstrates:

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

You might also like