本文是 Django 基于类的视图(CBV)系列的第五篇,主要介绍如何通过 CreateView、UpdateView、DeleteView 容易地实现 CRUD。结合之前提到的 ListView 和 DetailView,可以快速构建一个完整的 CRUD 应用程序,支持 数据读取、创建(Create)、修改(Update) 和 删除(Delete) 功能。
如果您还没有阅读上一篇文章 ListView 和 DetailView,建议您先阅读之前的内容。
基于类的视图(CBV)探索系列 ④ - ListView 和 DetailView 的使用方法
“利用 Django 的通用视图轻松完成 CRUD,提高生产力!”
在之前的文章中,我们关注了 CBV 的基本结构以及通过 ListView 和 DetailView 进行的 读取(READ) 操作。
在本文中,我们将探讨 Django 提供的便捷的 CreateView、UpdateView 和 DeleteView,使得创建(Create)、修改(Update) 和 删除(Delete) 的功能可以系统化地完善应用程序。
1. CreateView – 创建数据
1.1 基本概念和结构
CreateView 是 Django 通用视图中专门用于“创建新对象”的类。
-
自动化表单处理: 内部利用
FormView
功能,在form_valid()
中保存新对象并在成功时重定向到指定 URL。 -
与 ModelForm 配合良好: 指定
model
属性及fields
或form_class
,即可自动生成并处理表单。
# views.py
from django.views.generic.edit import CreateView
from django.urls import reverse_lazy
from .models import Post
class PostCreateView(CreateView):
model = Post
fields = ['title', 'content'] # 或者 form_class = PostForm
template_name = 'post_form.html'
success_url = reverse_lazy('post_list') # 创建成功后转到的 URL
1.2 urls.py 连接示例
# urls.py
from django.urls import path
from .views import PostCreateView
urlpatterns = [
path('posts/create/', PostCreateView.as_view(), name='post_create'),
]
1.3 模板示例: post_form.html
<!DOCTYPE html>
<html>
<head>
<title>撰写新文章</title>
</head>
<body>
<h1>撰写新帖子</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">保存</button>
</form>
</body>
</html>
提示: 使用
form_class
替代fields
可以在forms.py
中定义ModelForm
,以更精细地控制表单。
2. UpdateView – 修改数据
2.1 基本概念和结构
UpdateView 是专门用于查找并 修改 现有对象 的通用视图。
-
使用 URL 中的 pk 或 slug 值自动查询相关对象。
-
表单渲染时会自动填入现有数据,用户修改后提交后,变更将保存到数据库。
# views.py
from django.views.generic.edit import UpdateView
from django.urls import reverse_lazy
from .models import Post
class PostUpdateView(UpdateView):
model = Post
fields = ['title', 'content']
template_name = 'post_form.html'
success_url = reverse_lazy('post_list') # 修改成功后转到的 URL
2.2 urls.py 连接示例
# urls.py
from .views import PostUpdateView
urlpatterns = [
path('posts/<int:pk>/edit/', PostUpdateView.as_view(), name='post_update'),
]
2.3 模板示例(可重用)
与 CreateView 类似,可以重用 post_form.html 模板。
在 UpdateView 中,form.instance
已经是数据库中保存的对象,因此现有数据会自动填入表单。
3. DeleteView – 删除数据
3.1 基本概念和结构
DeleteView 是查找特定对象并进行 删除 的通用视图。
-
用户提交删除确认表单后,相关对象将从数据库中移除,并重定向到指定 URL。
-
为了安全起见,建议创建一个“删除确认”的模板。
# views.py
from django.views.generic.edit import DeleteView
from django.urls import reverse_lazy
from .models import Post
class PostDeleteView(DeleteView):
model = Post
template_name = 'post_confirm_delete.html'
success_url = reverse_lazy('post_list')
3.2 urls.py 连接示例
# urls.py
from .views import PostDeleteView
urlpatterns = [
path('posts/<int:pk>/delete/', PostDeleteView.as_view(), name='post_delete'),
]
3.3 模板示例: post_confirm_delete.html
<!DOCTYPE html>
<html>
<head>
<title>删除帖子</title>
</head>
<body>
<h1>删除帖子</h1>
<p>您确定要删除这篇文章吗?</p>
<form method="post">
{% csrf_token %}
<button type="submit">删除</button>
<a href="{% url 'post_list' %}">取消</a>
</form>
</body>
</html>
注意: DeleteView 被设计成要经过“删除确认”流程,以防止用户误删。
如果想要直接删除,必须使用其他方式(如 FormView 或直接编写逻辑)实现。
4. 一览 CRUD 完成流程
4.1 示例模型: Post
# models.py
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
4.2 urlpatterns(简化版本)
urlpatterns = [
# 1) 读取
path('posts/', PostListView.as_view(), name='post_list'), # 列表(ListView)
path('posts/<int:pk>/', PostDetailView.as_view(), name='post_detail'), # 详细(DetailView)
# 2) 创建
path('posts/create/', PostCreateView.as_view(), name='post_create'),
# 3) 更新
path('posts/<int:pk>/edit/', PostUpdateView.as_view(), name='post_update'),
# 4) 删除
path('posts/<int:pk>/delete/', PostDeleteView.as_view(), name='post_delete'),
]
4.3 推荐的目录结构和模板文件
-
templates/
-
post_list.html
-
post_detail.html
-
post_form.html
(CreateView 和 UpdateView 共用) -
post_confirm_delete.html
(DeleteView)
-
5. 如何自定义 Create/Update/DeleteView
5.1 使用 form_class 进行细分表单控制
class PostCreateView(CreateView):
model = Post
form_class = PostForm # 指定 ModelForm
...
PostForm
可以更详细地设置 字段验证 或 小部件指定,以实现更灵活的表单处理。
5.2 使用 get_success_url() 进行动态重定向
def get_success_url(self):
# 例如: 使用新创建的 Post 的 pk 转到详细页面
return reverse_lazy('post_detail', kwargs={'pk': self.object.pk})
self.object
指向当前 Create/Update 正在处理的模型实例。
5.3 添加权限控制,使用 Mixin
-
可以与 LoginRequiredMixin 等结合,实现“仅登录用户可以创建/修改/删除”的功能。
-
如果希望更细致地管理权限,可以考虑使用 PermissionRequiredMixin 或 UserPassesTestMixin。
6. 与 FBV 进行比较
功能 | FBV (函数基视图) | Create/Update/DeleteView (基于类的视图) |
---|---|---|
创建(Create) | request.method == 'POST' 条件语句,手动定义 ModelForm ,手动编写保存逻辑 |
CreateView: 继承后表单的创建、保存和重定向都自动处理 |
修改(Update) | 获取现有对象后放入表单,再次检验及保存逻辑重复 | UpdateView: 自动加载现有对象 -> 修改 -> 保存 |
删除(Delete) | GET -> 渲染删除确认页面,POST -> 进行删除处理,重定向逻辑混杂在函数中 | DeleteView: 获取删除目标对象、删除并处理重定向都提供内置逻辑 |
可读性 / 维护性 | 由于逻辑分支太多,代码容易变长,多个地方重复相同逻辑 | 通过 方法重写 仅重写所需部分,最小化重复 |
开发生产力(核心关键词) | “手动操作多,时间消耗大,代码重复” | “提高开发速度(节省时间)和维护性提升(生产力增强)” |
7. 总结:通过通用视图快速实现 CRUD!
利用 CreateView、UpdateView 和 DeleteView,您可以以极其简洁和直观的代码在 Django 中完成 CRUD 操作。
特别是,自动处理的 重复表单处理逻辑 和 数据保存后的重定向,使得开发者可以专注于“业务逻辑”和“UI/UX”。
现在,如果您已经理解
ListView
+DetailView
+CreateView
+UpdateView
+DeleteView
,就可以轻松构建基本的 CRUD 应用程序了!
在下一篇文章中,我们将讨论 TemplateView 和 RedirectView,探索如何顺利自动化 简单页面渲染 和 重定向 处理。
回顾上一篇文章
“通过利用 Django 的通用视图,自动化 CRUD 实现,
同时提升项目开发速度和代码质量!”
댓글이 없습니다.