Python · 2 分钟阅读
视图基础
视图 = 处理
HttpRequest、返回HttpResponse的可调用对象。
最简单的视图
# post/views.py
from django.http import HttpResponse
def hello(request):
return HttpResponse("<h1>Hello Django</h1>")
# config/urls.py
from django.urls import path
from post import views
urlpatterns = [
path("post/hello/", views.hello),
]
URLconf 模板
startproject 时生成的注释就是最佳实践示例:
# 函数视图
path("", views.home, name="home")
# 类视图
path("", Home.as_view(), name="home")
# include 分发
path("blog/", include("blog.urls"))
多 App 项目推荐每个 App 自带
urls.py,通过include挂载到根 URLconf。
HttpRequest 常用属性
| 属性 | 含义 |
|---|---|
method |
HTTP 方法 |
path |
URL 路径 |
GET / POST |
QueryDict,键值都是字符串 |
FILES |
上传文件 |
META |
WSGI 元信息(含 IP、UA 等) |
user |
当前登录用户(或 AnonymousUser) |
session |
会话字典 |
request.GET.get("a", 0) 是更安全的取值方式。
HttpResponse 常用子类
HttpResponse— 基类JsonResponse— 便捷返回 JSONHttpResponseRedirect— 302 重定向HttpResponseNotFound— 404
类视图(CBV)
from django.views import View
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse
class HelloView(View):
def get(self, request):
return HttpResponse("GET OK")
def post(self, request):
return HttpResponse("POST OK")
@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs)
注册:
path("hello/", HelloView.as_view())
View.dispatch 根据 HTTP 方法自动派发到 get / post / put / delete 等。
Mixin 复用
import time, functools
def exec_time(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
r = func(*args, **kwargs)
print(f"{func.__name__} took {time.perf_counter() - start:.3f}s")
return r
return wrapper
class TimedMixin:
@method_decorator(exec_time)
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs)
class HelloView(TimedMixin, View):
...
Django 内置常用 Mixin:LoginRequiredMixin、UserPassesTestMixin、PermissionRequiredMixin 等。
动态路由
# urls.py
path("dynamic/<int:year>/<mth:month>/<int:day>/", views.dynamic_hello)
| 转换器 | 匹配 |
|---|---|
str |
任意非空字符串(默认) |
int |
整数 |
slug |
字母数字 + - + _ |
uuid |
UUID |
path |
包含 / 的字符串 |
自定义转换器:
from django.urls import register_converter
class MonthConverter:
regex = r"0?[1-9]|1[0-2]"
def to_python(self, value): return int(value)
def to_url(self, value): return f"{value:02d}"
register_converter(MonthConverter, "mth")
给 post 应用写三个视图
# post/services.py
def build_topic_info(topic):
return {
"id": topic.id,
"title": topic.title,
"user": topic.user.username,
"created_time": topic.created_time.isoformat(),
}
# post/views.py
from django.http import JsonResponse
from django.shortcuts import get_object_or_404
from .models import Topic, Comment
from .services import build_topic_info
def topic_list(request):
qs = Topic.objects.all()
return JsonResponse({
"count": qs.count(),
"results": [build_topic_info(t) for t in qs],
})
def topic_detail(request, pk):
topic = get_object_or_404(Topic, pk=pk)
return JsonResponse(build_topic_info(topic))
def add_comment(request):
topic = get_object_or_404(Topic, pk=request.POST.get("id", 0))
content = request.POST.get("content", "")
if content:
comment = Comment.objects.create(topic=topic, content=content)
return JsonResponse({"id": comment.id})
return JsonResponse({})
get_object_or_404在 4.2+ 起推荐使用新版快捷方式,与 FBV/CBV 都适配。