Views and URLs
Routing HTTP requests using urls.py and handling logic via FBVs and CBVs.
🧑🏫 Sabse pehle — simple mein samjho#
Jab koi user browser mein ek link type karta hai (jaise website.com/about/), toh Django sabse pehle urls.py check karta hai ki kya ye rasta (route) uske paas hai? Agar mil gaya, toh wo us raste ke sath jude hue View (Python function ya class) ko call karta hai. View database se data uthata hai aur use HTML template mein daal kar user ko wapas bhej deta hai. Views likhne ke do tareeqe hain: Functions (FBV) aur Classes (CBV).
1. URL Routing (urls.py)#
Every Django project has a main urls.py file. Best practice dictates that you shouldn't put all your app routes in this main file. Instead, the main file should include() the URLs from your individual apps.
myproject/urls.py (The Master Router)
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
# Forward any URL starting with 'blog/' to the blog app's urls.py
path('blog/', include('blog.urls')),
]
blog/urls.py (The App Router)
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='blog-home'), # Maps to /blog/
# Path parameter: Captures an integer and passes it to the view as 'pk' (Primary Key)
path('post/<int:pk>/', views.post_detail, name='post-detail'),
]
(The name argument is incredibly important. It allows you to dynamically generate URLs in your templates instead of hardcoding them).
2. Function-Based Views (FBVs)#
The simplest way to write a view is using a standard Python function. It must take an HttpRequest object as its first parameter and must return an HttpResponse object (or render a template).
# blog/views.py
from django.shortcuts import render, get_object_or_404
from .models import Post
def home(request):
# Fetch all posts from the DB
posts = Post.objects.all()
# Pass them into a dictionary called 'context'
context = {
'posts': posts
}
# Render combines the HTML template with the context data to produce the final webpage
return render(request, 'blog/home.html', context)
def post_detail(request, pk):
# This automatically throws a 404 page if the post doesn't exist
post = get_object_or_404(Post, pk=pk)
return render(request, 'blog/detail.html', {'post': post})
3. Class-Based Views (CBVs)#
As your application grows, you'll realize that rendering a list of items or creating a new item involves writing the exact same boilerplate code over and over. Django provides Class-Based Views (CBVs) to handle these standard operations automatically. You just inherit from a built-in class, provide a couple of variables, and Django does the rest!
from django.views.generic import ListView, DetailView
from .models import Post
# Does the exact same thing as the home() FBV above!
class PostListView(ListView):
model = Post
template_name = 'blog/home.html' # Override default template name
context_object_name = 'posts' # Override default context variable name
ordering = ['-created_at'] # Sort by newest first
# Does the exact same thing as the post_detail() FBV above!
class PostDetailView(DetailView):
model = Post
# By default, it expects a template at <app>/<model>_detail.html
# By default, the context variable is called 'object' or 'post'
To use a CBV in your urls.py, you must call its .as_view() method:
path('', views.PostListView.as_view(), name='blog-home'),
Which should you use? Use CBVs for standard CRUD operations (Create, Read, Update, Delete) to save time. Use FBVs for highly custom, complex logic where CBVs become too confusing to override.