Django & Flask Topic

Django Views and URL Configuration

Introduction to Views and URLs

Views and URL configuration form the core routing mechanism of any Django application. They work together to determine what content gets displayed when a user visits a specific URL.

Function-Based Views (FBVs)

Function-Based Views are the simplest way to create views in Django. They are Python functions that take a web request and return a web response.

Basic View Structure

python

# myapp/views.py
from django.http import HttpResponse

def simple_view(request):
    return HttpResponse("Hello, World! This is a simple view.")

URL Routing with path()

Basic URL Configuration

python

# myproject/urls.py (Project level)
from django.contrib import admin
from django.urls import path, include
from myapp import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('hello/', views.simple_view, name='hello'),
    path('blog/', include('blog.urls')),  # Include app-specific URLs
]

# blog/urls.py (App level - create this file)
from django.urls import path
from . import views

urlpatterns = [
    path('', views.blog_home, name='blog_home'),
    path('about/', views.about, name='about'),
]

The HttpResponse Shortcut

HttpResponse is used to return simple text responses.

python

# myapp/views.py
from django.http import HttpResponse

def current_time(request):
    from datetime import datetime
    now = datetime.now()
    return HttpResponse(f"Current time: {now.strftime('%Y-%m-%d %H:%M:%S')}")

def greet_user(request):
    return HttpResponse("Welcome to our website!")

The render Shortcut

The render shortcut is used to render HTML templates with context data.

Basic Template Rendering

python

# myapp/views.py
from django.shortcuts import render

def home_page(request):
    context = {
        'title': 'Welcome to My Site',
        'message': 'This is the home page content.'
    }
    return render(request, 'myapp/home.html', context)

# Create template at: myapp/templates/myapp/home.html

Template File Example

html

<!-- myapp/templates/myapp/home.html -->
<!DOCTYPE html>
<html>
<head>
    <title>{{ title }}</title>
</head>
<body>
    <h1>{{ title }}</h1>
    <p>{{ message }}</p>
</body>
</html>

Capturing URL Parameters

Single Parameter

python

# URLs configuration
from django.urls import path
from . import views

urlpatterns = [
    path('user/<str:username>/', views.user_profile, name='user_profile'),
    path('post/<int:post_id>/', views.post_detail, name='post_detail'),
]

# Views handling parameters
def user_profile(request, username):
    return HttpResponse(f"Hello, {username}! This is your profile.")

def post_detail(request, post_id):
    return HttpResponse(f"Viewing post with ID: {post_id}")

Multiple Parameters

python

# URLs with multiple parameters
urlpatterns = [
    path('category/<str:category>/<int:year>/', views.category_archive, name='category_archive'),
]

# View handling multiple parameters
def category_archive(request, category, year):
    return HttpResponse(f"Showing {category} posts from {year}")

Path Converters

Django provides several built-in path converters:

  • str - Matches any non-empty string (default)

  • int - Matches zero or any positive integer

  • slug - Matches slug strings (letters, numbers, hyphens, underscores)

  • uuid - Matches UUID strings

  • path - Matches any string including path separators (/)

python

# Using different converters
urlpatterns = [
    path('product/<slug:product_slug>/', views.product_detail, name='product_detail'),
    path('file/<path:file_path>/', views.serve_file, name='serve_file'),
    path('order/<uuid:order_id>/', views.order_detail, name='order_detail'),
]

Practical Examples

Example 1: Blog Application Views

python

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

def post_list(request):
    """Display all blog posts"""
    posts = Post.objects.all()
    context = {
        'posts': posts,
        'page_title': 'All Blog Posts'
    }
    return render(request, 'blog/post_list.html', context)

def post_detail(request, post_id):
    """Display a single blog post"""
    post = get_object_or_404(Post, id=post_id)
    context = {
        'post': post
    }
    return render(request, 'blog/post_detail.html', context)

def post_by_category(request, category_slug):
    """Display posts by category"""
    posts = Post.objects.filter(category__slug=category_slug)
    context = {
        'posts': posts,
        'category': category_slug
    }
    return render(request, 'blog/category_posts.html', context)

Corresponding URL Configuration

python

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

urlpatterns = [
    path('', views.post_list, name='post_list'),
    path('post/<int:post_id>/', views.post_detail, name='post_detail'),
    path('category/<slug:category_slug>/', views.post_by_category, name='posts_by_category'),
    path('archive/<int:year>/<int:month>/', views.monthly_archive, name='monthly_archive'),
]

# myproject/urls.py
from django.urls import path, include

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

Example 2: E-commerce Views

python

# store/views.py
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse
from .models import Product, Category

def product_list(request):
    products = Product.objects.all()
    return render(request, 'store/product_list.html', {'products': products})

def product_detail(request, product_slug):
    product = get_object_or_404(Product, slug=product_slug)
    return render(request, 'store/product_detail.html', {'product': product})

def category_products(request, category_id):
    category = get_object_or_404(Category, id=category_id)
    products = Product.objects.filter(category=category)
    return render(request, 'store/category_products.html', {
        'category': category,
        'products': products
    })

Advanced URL Patterns

Optional Parameters with Custom Path Converters

python

# You can create custom path converters for complex patterns
class YearConverter:
    regex = '[0-9]{4}'
    
    def to_python(self, value):
        return int(value)
    
    def to_url(self, value):
        return str(value)

# Register in urls.py
from django.urls import register_converter
register_converter(YearConverter, 'yyyy')

urlpatterns = [
    path('archive/<yyyy:year>/', views.year_archive, name='year_archive'),
]

Including URL Namespaces

python

# blog/urls.py
app_name = 'blog'  # URL namespace

urlpatterns = [
    path('', views.post_list, name='post_list'),
    path('post/<int:post_id>/', views.post_detail, name='post_detail'),
]

# Usage in templates: {% url 'blog:post_detail' post_id=1 %}

Request Object Methods

Understanding the request object is crucial for view development:

python

def advanced_view(request):
    # Request method checking
    if request.method == 'GET':
        # Handle GET request
        search_query = request.GET.get('q', '')  # Get query parameter
        return HttpResponse(f"Searching for: {search_query}")
    
    elif request.method == 'POST':
        # Handle POST request
        username = request.POST.get('username')
        return HttpResponse(f"Hello, {username}!")
    
    # Other useful request attributes
    user_agent = request.META.get('HTTP_USER_AGENT')
    user_ip = request.META.get('REMOTE_ADDR')
    
    return HttpResponse(f"User Agent: {user_agent}, IP: {user_ip}")

Error Handling Views

python

# Custom error views
def custom_404(request, exception):
    return render(request, '404.html', status=404)

def custom_500(request):
    return render(request, '500.html', status=500)

# Add to urls.py
handler404 = 'myapp.views.custom_404'
handler500 = 'myapp.views.custom_500'

Best Practices

1. Keep Views Focused

python

# Good - focused view
def user_profile(request, user_id):
    user = get_object_or_404(User, id=user_id)
    return render(request, 'users/profile.html', {'user': user})

# Bad - doing too much
def messy_view(request, user_id):
    # User logic, post logic, comment logic all in one view
    pass

2. Use Meaningful URL Names

python

# Good
path('users/<int:user_id>/profile/', views.user_profile, name='user_profile')

# Bad
path('page1/', views.view1, name='view1')

3. Handle Different HTTP Methods

python

def contact_form(request):
    if request.method == 'POST':
        # Process form submission
        name = request.POST.get('name')
        email = request.POST.get('email')
        # Save to database, send email, etc.
        return HttpResponse("Thank you for your message!")
    else:
        # Display empty form
        return render(request, 'contact/form.html')

Complete Working Example

Let's create a complete blog URL and view setup:

python

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

app_name = 'blog'

urlpatterns = [
    path('', views.post_list, name='post_list'),
    path('post/<int:post_id>/', views.post_detail, name='post_detail'),
    path('category/<slug:category_slug>/', views.category_posts, name='category_posts'),
    path('author/<str:username>/', views.author_posts, name='author_posts'),
    path('search/', views.search_posts, name='search_posts'),
]

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

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

def post_detail(request, post_id):
    post = get_object_or_404(Post, id=post_id)
    return render(request, 'blog/post_detail.html', {'post': post})

def category_posts(request, category_slug):
    category = get_object_or_404(Category, slug=category_slug)
    posts = Post.objects.filter(category=category)
    return render(request, 'blog/category_posts.html', {
        'category': category,
        'posts': posts
    })

def search_posts(request):
    query = request.GET.get('q', '')
    if query:
        posts = Post.objects.filter(title__icontains=query)
    else:
        posts = Post.objects.none()
    
    return render(request, 'blog/search_results.html', {
        'posts': posts,
        'query': query
    })

This foundation in views and URL configuration will enable you to build complex web applications with clean, maintainable URL structures and logical view handling.

Comments (0)

No comments yet. Be the first to comment!

LecturreAI Assistant

Hello! I'm LecturreAI

What would you like to learn today?