Python · 1 分钟阅读
通用类视图
Django 为常见场景预制了高度可复用的视图基类:少写代码,多做对的事。
TemplateView
只渲染模板的场景:
from django.views.generic import TemplateView
class IndexView(TemplateView):
template_name = "post/index.html"
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
ctx["hello"] = "Hello Django"
return ctx
path("index/", IndexView.as_view())
RedirectView
from django.views.generic import RedirectView
class TopicRedirect(RedirectView):
pattern_name = "post:topic_detail"
permanent = False # True 即 301
query_string = True # 保留原 URL 查询参数
ListView
from django.views.generic import ListView
from post.models import Topic
class TopicListView(ListView):
model = Topic
template_name = "post/topic_list.html" # 默认 <app>/<model>_list.html
context_object_name = "topics" # 默认 <model>_list
paginate_by = 20
ordering = ("-created_time",)
模板里:
{% for topic in topics %}
{{ topic.title }}
{% endfor %}
{% if is_paginated %}
{% if page_obj.has_previous %}<a href="?page={{ page_obj.previous_page_number }}">上一页</a>{% endif %}
{% endif %}
DetailView
from django.views.generic import DetailView
class TopicDetailView(DetailView):
model = Topic
context_object_name = "topic"
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
ctx["comments"] = self.object.comments.order_by("-created_time")
return ctx
path("topic/<int:pk>/", TopicDetailView.as_view(), name="topic_detail")
模板默认名:<app>/<model>_detail.html。
CreateView / UpdateView / DeleteView
from django.urls import reverse_lazy
from django.views.generic import CreateView, UpdateView, DeleteView
from post.models import Topic
class TopicCreateView(LoginRequiredMixin, CreateView):
model = Topic
fields = ("title", "content")
success_url = reverse_lazy("post:topic_list")
def form_valid(self, form):
form.instance.user = self.request.user
return super().form_valid(form)
何时选 FBV / CBV?
| 场景 | 建议 |
|---|---|
| 简单表单 / API 端点 | FBV + DRF |
| 标准 CRUD | CBV(ListView / DetailView / CreateView) |
| 复杂业务流、组合多个步骤 | FBV 或 CBV + Service 层 |
| 需要 Mixin 复用 | CBV |