Django笔记&教程 7-3 拓展CBVs(Class-based views)
Django 自学笔记兼学习教程第7章第3节——拓展CBVs(Class-based views)
点击查看教程总目录
一般而言,直接使用原生的Class-based views,能展现的样式和内容是固定的。
为了根据实际情况去定制View,我们需要继承django自带的View并修改。
在修改之前,我们需要先了解下CBVs。
1 CBV的HTTP方法
先上一个例子,如果要用视图方法来处理各种HTTP方法,代码大概会如下:
# views.py
def simple_function_based_view(request):
if request.method == 'GET':
... # code to process a GET request
elif request.method == 'POST':
... # code to process a POST request
而使用CBV来处理的话,代码如下:
# views.py
from django.views import View
class SimpleClassBasedView(View):
def get(self, request):
... # code to process a GET request
def post(self, request):
... # code to process a POST request
对于浏览器发起的请求中使用的特定HTTP方法(GET、POST等),判断处理的代码组织可以通过CBV中单独的方法来解决,而不是通过条件分支。
且HTTP方法与CBV中单独的方法通过小写的方式匹配。
- 即GET请求,对应CBV中的
get方法; - POST请求,对应CBV中的
post方法; - 其他请求同理
2 Class-based views常用方法
get_context_data()
Returns context data for displaying the object.
The base implementation of this method requires that theself.objectattribute be set by the view (even ifNone). Be sure to do this if you are using this mixin without one of the built-in views that does so.
It returns a dictionary with these contents:
object: The object that this view is displaying (self.object).
context_object_name:self.objectwill also be stored under the name returned byget_context_object_name(), which defaults to the lowercased version of the model name.
返回用于显示对象的context数据,返回包含以下内容的词典:
object:此视图显示的对象(self.object).context_object_name:self.object还将存储在get_context_object_name()返回的名称下,该名称默认为模型名称的小写版本。
PS: 需要修改context数据,可重写此方法
例子如下(出处:adding-extra-context)
class PublisherDetail(DetailView):
model = Publisher
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super().get_context_data(**kwargs)
# Add in a QuerySet of all the books
context['book_list'] = Book.objects.all()
return context
3 实例
拓展CreateView
欲实现:学生注册时,学生选择年级后注册,自动根据年级按序生成年级子学号
具体来说,一个年级没有学生的话,那么新注册的学生学号就是000001
一个年级有学生的话,取出所有学生里面的最大学号,新注册的学生学号就是最大学号增加1。
首先为学生注册实现一个表单,这个在之前第六章第四节
中有专门做过,这里直接把代码结果拿来用,关于代码的具体意思有不懂的,可以回去看一看
此时my_app/forms.py
from django import forms
from .models import Student
class StuRegisterForm(forms.ModelForm):
confirm_password = forms.CharField(widget=forms.PasswordInput(), label="确认密码")
class Meta:
model = Student
fields = ('grade',
'name',
'password',
'confirm_password',
'gender',
'birthday',
'email',
'info')
def clean(self):
cleaned_data = super(StuRegisterForm, self).clean()
password = cleaned_data.get('password')
confirm_password = cleaned_data.get('confirm_password')
if confirm_password != password:
self.add_error('confirm_password', 'Password does not match.')
return cleaned_data
my_app/views/register.py
from django.shortcuts import render
from django.http.response import HttpResponse,HttpResponseRedirect
from .models import Student
from django.views.generic import CreateView
from .forms import RegisterForm
class CreateStudentView(CreateView):
model = Student
form_class = RegisterForm
# fields = "__all__"
template_name = "register.html"
success_url = "login"
def form_valid(self, form):
# 学生注册时选定年级自动生成学号
grade = form.cleaned_data["grade"]
# order_by默认升序排列,number前的负号表示降序排列
student_set = Student.objects.filter(grade=grade).order_by("-number")
if student_set.count() > 0:
last_student = student_set[0]
new_number = str(int(last_student.number) + 1)
for i in range(6 - len(new_number)):
new_number = "0" + new_number
else:
new_number = "000001"
# Create, but don't save the new student instance.
new_student = form.save(commit=False)
# Modify the student
new_student.number = new_number
# Save the new instance.
new_student.save()
# Now, save the many-to-many data for the form.
form.save_m2m()
self.object = new_student
return HttpResponseRedirect(self.get_success_url())
对应urls.py里面的urlpatterns变量,添加对应的urlpattern如下
from django.urls import path
from my_app.views import login, register
from my_app import view
urlpatterns = [
path('login/', login.page, name="login"),
path('hello/', view.hello),
path('register', register.CreateStudentView.as_view(),
name="register"),
]
其中,用到的关联代码还有:
register.html见 6-1 基于类的视图(Class-based views)介绍Student模型见Django自学笔记 4-1 模型(Models)介绍中的示例。- 其他代码见本专栏之前博客(实际上本文用不到)
以上代码,只介绍下本节相关的内容,其他的
主要说下CreateStudentView,
这个类首先继承了CreateView类,
然后重写了了专门的form_valid方法,根据自定义的需求,重新实现通过form表单内容生成model实例并保存的过程,并返回了自定义的重定向对象。
可能有人这里会对该方法感到疑惑,这里我们需要去看一下一些方法的源码,便于进一步的理解。
(以下算是进阶内容,是通过不断深入其代码源码分析出来的,不太看得懂的话推荐略过,暂时理解为可以在form_valid方法中重新定义“通过form表单内容生成model实例并保存”的逻辑。)
这个方法是用来处理提交表单的请求的,即POST请求,那么我们看下CreateView的post方法,其post方法是继承BaseCreateView的post方法:
def post(self, request, *args, **kwargs):
self.object = None
return super().post(request, *args, **kwargs)
其中返回值中又调用了父类的post方法,即ProcessFormView的post方法:
def post(self, request, *args, **kwargs):
"""
Handle POST requests: instantiate a form instance with the passed
POST variables and then check if it's valid.
"""
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
阅读这个代码,我们可以判断出,其表单生成模型保存的过程应该只会是在return self.form_valid(form)这一句中,前面两句一句是获取表单内容,一句是验证表单。
然后我们再去看它的form_valid方法,CreateView的form_valid方法是继承ModelFormMixin的form_valid方法
def form_valid(self, form):
"""If the form is valid, save the associated model."""
self.object = form.save()
return super().form_valid(form)
这个方法中先进行了form表单数据的保存(即生成模型实例保存到数据库中)并赋值给self.object,
然后又调用了父类的form_valid方法,即FormMixin的form_valid方法
def form_valid(self, form):
"""If the form is valid, redirect to the supplied URL."""
return HttpResponseRedirect(self.get_success_url())
该方法实现了返回重定向对象的功能,
所以我们要去实现的form_valid要实现上面两个工作
ModelFormMixin的form_valid方法中的:form表单数据的保存(即生成模型实例保存到数据库中)并赋值给self.object,FormMixin的form_valid方法中的:返回重定向对象的功能
Django笔记&教程 7-3 拓展CBVs(Class-based views)的更多相关文章
- Django笔记&教程 总目录
本篇博客只有目录,正文内容在目录章节链接的博客里 除目录本身外,没有链接的章节,说明内容还没开始编辑 本项目笔记仍在不断创作中,还有些内容会根据自身所学不断更新完善 本项目主要为markdwon文档, ...
- Django笔记&教程 7-1 基于类的视图(Class-based views)介绍
Django 自学笔记兼学习教程第7章第1节--基于类的视图(Class-based views)介绍 点击查看教程总目录 1 介绍 Class-based views (CBVs) are view ...
- Django笔记&教程 2-2 URL详细匹配规则
Django 自学笔记兼学习教程第2章第2节--URL详细匹配规则 点击查看教程总目录 本章第一节中我们简单介绍了URL与View关系 简单概括来说,网页请求的url会通过urls.py里面的urlp ...
- Django笔记&教程 3-3 模板常用语法
Django 自学笔记兼学习教程第3章第3节--模板常用语法 点击查看教程总目录 本文主要参考:https://docs.djangoproject.com/en/2.2/ref/templates/ ...
- Django笔记&教程 6-4 forms进阶操作,重写forms方法
Django 自学笔记兼学习教程第6章第4节--forms进阶操作,重写forms方法 点击查看教程总目录 1 - 重写clean方法 在本章第三节中,我们举了个注册学生账号的例子,里面我们使用模型来 ...
- Django笔记&教程 0-1 前言
Django 自学笔记兼学习教程第0章第1节--前言 点击查看教程总目录 1 最初的想法 自学Django已经有一段时间了,自认收获不少,学的还算可以,然而实际去做项目写代码的时候,很多用法记得不清, ...
- Django笔记&教程 0-2 框架版本与相关工具
Django 自学笔记兼学习教程第0章第2节-- 框架版本与相关工具 点击查看教程总目录 1 版本 python: 3.6.5 Django: 2.2.11 (有些地方我也会对比下各种版本的区别) 安 ...
- Django笔记&教程 1-1 一 新建项目
Django 自学笔记兼学习教程第1章第1节--一 新建项目 点击查看教程总目录 1- 命令行新建Django项目 新建项目命令(project_name处为项目名) django-admin sta ...
- Django笔记&教程 1-2 二 常用配置
Django 自学笔记兼学习教程第1章第2节--二 常用配置 点击查看教程总目录 新手建议简单浏览本文,不理解的建议跳过,不要强行理解. Django的设置涉及多个模块,需要了解Django的一些相关 ...
随机推荐
- MyBatis-Plus——实践篇
MyBatis-Plus--实践篇 MyBatis-Plus (简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发.提高效率而生.进行数据库操作常用 ...
- LightningChart XY功能中的常见问题
LightningChart XY功能中的常见问题 XY 是LightningChart 的重要功能之一,也是被用户使用最广泛的.用户经常对这个功能有着这样那样的疑问,现在将一些常用问题汇总了一下,希 ...
- Serverless 在 SaaS 领域的最佳实践
作者 | 计缘 来源 | Serverless 公众号 随着互联网人口红利逐渐减弱,基于流量的增长已经放缓,互联网行业迫切需要找到一片足以承载自身持续增长的新蓝海,产业互联网正是这一宏大背景下的新趋势 ...
- 题解 [JSOI2011]柠檬
题目传送门 题目大意 给出一个区间,每个点都有一个颜色,把这个区间分为许多块,每一块的权值为 \(\max\{s\times t^2\}\) ,其中 \(s\) 为某种颜色,\(t\) 为该颜色在该块 ...
- 哈工大知识图谱(Knowledge Graph)课程概述
一.什么是知识图谱 知识(Knowledge)可以理解为 精炼的数据,知识图谱(Knowledge Graph)即是对知识的图形化表示,本质上是一种大规模语义网络 (semantic network) ...
- SQL Server 数据库单用户模式处理
在还原数据库bak备份文件时,由于某种原因(具体何种原因在此不进行分析)导致数据库还原后处于单用户模式,如下图: 单个用户模式导致,数据库无法打开,只能通过脚本去查询数据库内的表,然后进行查询数据,极 ...
- Linux常用命令,查看树形结构、删除目录(文件夹)、创建文件、删除文件或目录、复制文件或目录(文件夹)、移动、查看文件内容、权限操作
5.查看树结构(tree) 通常情况下系统未安装该命令,需要yum install -y tree安装 直接使⽤tree显示深度太多,⼀般会使⽤ -L选项⼿⼯设定⽬录深度 格式:tree -L n [ ...
- 半天撸一个简易版mybatis
为什么需要持久层框架? 首先我们先看看使用原生jdbc存在的问题? public static void main(String[] args) { Connection connection = n ...
- SharkCTF2021 Classic_Crypto_king2
crypto类题. 题面如下: 前面的代码给出了原理:后面的字符串第一行是print出的key,第二行是密文. 加密原理是,首先对table进行乱序处理,然后将明文flag按照(顺序table--&g ...
- 【数据结构与算法Python版学习笔记】算法分析
什么是算法分析 算法是问题解决的通用的分步的指令的聚合 算法分析主要就是从计算资源的消耗的角度来评判和比较算法. 计算资源指标 存储空间或内存 执行时间 影响算法运行时间的其他因素 分为最好.最差和平 ...