100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Python

Function-Based Views

Learn how Django's function-based views (FBVs) take a request and return a response using plain Python functions, and when they're the right choice over class-based views.

Views & URLsBeginner8 min readJul 10, 2026
Analogies

What Is a Function-Based View?

A function-based view (FBV) in Django is simply a Python function that takes an HttpRequest object as its first argument and returns an HttpResponse object (or a subclass like JsonResponse or render()'s output). Django's URL dispatcher calls this function whenever a matching URL pattern is requested, passing along any captured URL parameters as extra arguments. Because it is just a function, an FBV has no hidden machinery: the entire request-handling logic is visible top to bottom in one place.

🏏

Cricket analogy: It's like a specialist bowler brought on for one specific over: the captain (URL dispatcher) hands the ball (request) to a named bowler (function), who delivers it and returns the outcome directly, no fielding changes hidden elsewhere.

Writing and Registering an FBV

A minimal FBV imports HttpResponse or the render() shortcut, accepts request as its first parameter, and returns a response object built from a template and context dictionary. You register it by importing the function into urls.py and mapping a path() entry to it directly, so Django can call it when the URL matches. Decorators such as @login_required or @require_http_methods can be stacked directly above the function definition to add cross-cutting behavior like authentication checks or restricting allowed HTTP verbs.

🏏

Cricket analogy: It's like naming a designated closer in cricket, such as MS Dhoni finishing an innings: you assign that specific function to the death overs (URL pattern) in the team sheet (urls.py) so the captain knows exactly who to call.

python
# views.py
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
from .models import Article

@login_required
def article_detail(request, article_id):
    article = get_object_or_404(Article, pk=article_id)
    return render(request, 'articles/detail.html', {'article': article})

# urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('articles/<int:article_id>/', views.article_detail, name='article_detail'),
]

Handling Different HTTP Methods

Because an FBV is one function, it must manually branch on request.method to support GET, POST, and other verbs in the same view, typically with an if/elif chain such as if request.method == 'POST':. This gives full control over the flow — you decide exactly when to validate a form, save an object, or redirect — but it also means the branching logic can grow tangled if a view supports many methods or many conditional paths, which is the main scaling weakness FBVs have compared to class-based views.

🏏

Cricket analogy: It's like a bowler changing their delivery mid-over based on the batter's stance: same over (function), but an if/elif inside decides whether to bowl a yorker or a bouncer depending on conditions.

Django's function-based generic shortcuts (render, redirect, get_object_or_404) exist precisely to keep FBVs concise, so you rarely need to write raw HttpResponse or manual template loading by hand.

FBVs offer no built-in inheritance or mixin reuse, so if several views need identical logic (e.g., pagination, permission checks), you must either duplicate code or manually extract it into a helper function and call it everywhere — class-based views solve this more systematically with mixins.

  • An FBV is a plain Python function taking request (plus URL-captured args) and returning an HttpResponse-like object.
  • Register FBVs in urls.py by importing the function and passing it directly to path() or re_path().
  • Decorators like @login_required and @require_http_methods add reusable behavior without subclassing.
  • Method handling (GET vs POST) must be branched manually inside the function body using request.method.
  • FBVs are explicit and easy to trace but do not support mixin-style code reuse the way class-based views do.
  • Shortcuts like render(), redirect(), and get_object_or_404() keep FBV code concise and idiomatic.
  • FBVs are a good fit for simple, one-off logic; complex CRUD-heavy views often benefit more from class-based views.

Practice what you learned

Was this page helpful?

Topics covered

#Python#DjangoStudyNotes#WebDevelopment#FunctionBasedViews#Function#Based#Views#View#Functions#StudyNotes#SkillVeris