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!