Django Views

Handling requests and returning responses

👁️ What are Django Views?

Views are Python functions or classes that receive web requests and return web responses. They contain the logic for processing user input, interacting with models, and rendering templates to display content.

def home(request):
    return render(request, 'home.html')

Types of Views

Function Views

Simple Python functions

def my_view(request):
    return HttpResponse('Hello')
🎯

Class Views

Object-oriented approach

class MyView(View):
    def get(self, request):
📋

Generic Views

Pre-built common patterns

class PostList(ListView):
    model = Post
🔄

API Views

Return JSON responses

return JsonResponse(data)

🔹 Function-Based Views (FBV)

Function-based views are simple Python functions that take a request object and return a response. They're straightforward and perfect for beginners.

🔸 Basic Function View

# blog/views.py
from django.shortcuts import render
from django.http import HttpResponse

def home(request):
    return HttpResponse("Welcome to my blog!")

def about(request):
    return render(request, 'blog/about.html')

def contact(request):
    context = {
        'email': '[email protected]',
        'phone': '123-456-7890'
    }
    return render(request, 'blog/contact.html', context)

Output:

Welcome to my blog!

🔹 Views with Database Queries

Views commonly retrieve data from models to display on web pages. Use Django's ORM to query the database efficiently.

# blog/views.py
from django.shortcuts import render, get_object_or_404
from .models import Post

def post_list(request):
    # Get all posts
    posts = Post.objects.all().order_by('-published_date')
    return render(request, 'blog/post_list.html', {'posts': posts})

def post_detail(request, pk):
    # Get single post or 404
    post = get_object_or_404(Post, pk=pk)
    return render(request, 'blog/post_detail.html', {'post': post})

def recent_posts(request):
    # Filter posts
    posts = Post.objects.filter(published_date__year=2024)[:5]
    return render(request, 'blog/recent.html', {'posts': posts})

🔹 Handling Form Submissions

Views process form data submitted by users. Check the request method to handle GET and POST requests differently.

# blog/views.py
from django.shortcuts import render, redirect
from .models import Post

def create_post(request):
    if request.method == 'POST':
        # Process form data
        title = request.POST.get('title')
        content = request.POST.get('content')
        
        # Create new post
        Post.objects.create(title=title, content=content)
        
        # Redirect after successful submission
        return redirect('post_list')
    
    # Display empty form for GET request
    return render(request, 'blog/create_post.html')
<!-- templates/blog/create_post.html -->
<form method="post">
    {% csrf_token %}
    <input type="text" name="title" placeholder="Title" required>
    <textarea name="content" placeholder="Content" required></textarea>
    <button type="submit">Create Post</button>
</form>

🔹 Class-Based Views (CBV)

Class-based views organize code using object-oriented programming. They provide reusable components and handle common patterns efficiently.

🔸 Basic Class View

# blog/views.py
from django.views import View
from django.shortcuts import render
from django.http import HttpResponse

class HomeView(View):
    def get(self, request):
        return render(request, 'blog/home.html')
    
    def post(self, request):
        # Handle POST request
        return HttpResponse("Form submitted!")

# blog/urls.py
from django.urls import path
from .views import HomeView

urlpatterns = [
    path('', HomeView.as_view(), name='home'),
]

🔹 Generic Class-Based Views

Django provides generic views for common patterns like listing objects, displaying details, creating, updating, and deleting records.

🔸 ListView - Display Multiple Objects

# blog/views.py
from django.views.generic import ListView
from .models import Post

class PostListView(ListView):
    model = Post
    template_name = 'blog/post_list.html'
    context_object_name = 'posts'
    ordering = ['-published_date']
    paginate_by = 10

🔸 DetailView - Display Single Object

from django.views.generic import DetailView

class PostDetailView(DetailView):
    model = Post
    template_name = 'blog/post_detail.html'
    context_object_name = 'post'

🔸 CreateView - Create New Object

from django.views.generic.edit import CreateView
from django.urls import reverse_lazy

class PostCreateView(CreateView):
    model = Post
    fields = ['title', 'content']
    template_name = 'blog/post_form.html'
    success_url = reverse_lazy('post_list')

🔹 Passing Context to Templates

Views pass data to templates using context dictionaries. Templates can then access this data to display dynamic content.

# blog/views.py
from django.shortcuts import render
from .models import Post, Author

def dashboard(request):
    context = {
        'total_posts': Post.objects.count(),
        'recent_posts': Post.objects.all()[:5],
        'authors': Author.objects.all(),
        'site_name': 'My Blog',
    }
    return render(request, 'blog/dashboard.html', context)
<!-- templates/blog/dashboard.html -->
<h1>{{ site_name }} Dashboard</h1>
<p>Total Posts: {{ total_posts }}</p>

<h2>Recent Posts</h2>
{% for post in recent_posts %}
    <p>{{ post.title }}</p>
{% endfor %}

🔹 HTTP Response Types

Django views can return different types of responses depending on your needs:

from django.http import HttpResponse, JsonResponse, HttpResponseRedirect
from django.shortcuts import render, redirect

# HTML Response
def html_view(request):
    return render(request, 'template.html')

# Plain Text Response
def text_view(request):
    return HttpResponse("Plain text response")

# JSON Response (for APIs)
def json_view(request):
    data = {'name': 'John', 'age': 30}
    return JsonResponse(data)

# Redirect Response
def redirect_view(request):
    return redirect('home')

# 404 Response
from django.http import Http404

def not_found_view(request):
    raise Http404("Page not found")

🔹 View Decorators

Decorators add functionality to views, such as requiring login or restricting HTTP methods:

from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_http_methods

# Require user to be logged in
@login_required
def profile(request):
    return render(request, 'profile.html')

# Only allow POST requests
@require_http_methods(["POST"])
def submit_form(request):
    # Process form
    return redirect('success')

# Allow only GET and POST
@require_http_methods(["GET", "POST"])
def contact(request):
    if request.method == 'POST':
        # Handle form submission
        pass
    return render(request, 'contact.html')

🧠 Test Your Knowledge

What is the first parameter of every Django view function?