序列化、CBV源码分析、模版层
一、
主要就是实现跨语言数据传输
py中:
json.dumps 序列化 json.loads 反序列化
js中:
JSON.stringify() # json.dumps JSON.parse() # json.loads
django中:
from django.http import JsonResponse
def index(request):
d = {'username': 'kevin哈喽', 'age': 18}
return JsonResponse(d, safe=False,json_dumps_params={'ensure_ascii': False})

通过设置safe=False,Django将允许序列化非字典类型的数据。这在您返回的数据不仅限于字典结构时非常有用,例如,您可以返回一个列表作为JSON响应。
1、form表单能上传文件的前提
<form action="" method="post" enctype="multipart/form-data"> 1. 请求方式必须是post 2. enctype必须是form-data
注:
enctype是编码类型的意思。
enctype="multipart/form-data" 是 HTML 表单元素中的一个属性,用于指定在提交表单时,浏览器要使用哪种编码类型来进行数据传输。它的作用是允许在表单中传输包含二进制数据(例如文件上传)的内容。
2、views代码
def sc_file(request):
# 接收提交的文件数据
# POST只能获取到post请求的普通数据,文件数据拿不到
print(request.POST.get('username'))
# <QueryDict: {'username': ['jack']}>
print(request.FILES) # 接收的是文件数据
# <MultiValueDict: {'my_file': [<InMemoryUploadedFile: 10056.jpg (image/jpeg)>]}>
if request.method == 'POST':
file_obj = request.FILES.get('my_file')
with open(file_obj.name, 'wb') as f:
for line in file_obj:
f.write(line)
return render(request, 'ff.html')
注:
1. 接收文件使用的是 request.FILES
2. with open(file_obj.name, 'wb') as f: 处file_obj.name改为file_obj就会报错:
TypeError at /sc_file/ expected str, bytes or os.PathLike object, not InMemoryUploadedFile
3、html文件
<form action="" method="post" enctype="multipart/form-data">
<input type="text" name="username">
<br>
上传文件:<input type="file" name="my_file">
<br>
<input type="submit" value="提交">
</form>
1、request.FILES
request.GET request.POST request.FILES request.path_info # /ab_request/ reqeust.path # /ab_request/ request.get_full_path() # /ab_request/ /ab_request/?username=kevin&age=11 request.body # 它能够接收浏览器发过来的二进制数据
1、CBV - Class-Based Views(基于类的视图)
CBV 是一种使用基于类的方式来实现视图的方法。它允许你将视图逻辑封装在类中,并通过类的方法来处理不同的 HTTP 请求方法(如 GET、POST 等)。
CBV 提供了很多内置的通用视图类,用于快速实现常见的 CRUD(创建、读取、更新、删除)操作。
2、FBV - Function-Based Views(基于函数的视图)
FBV 是一种使用函数的方式来实现视图的方法。在 FBV 中,每个视图都是一个独立的 Python 函数,根据不同的 HTTP 请求方法来处理请求。
在函数内部编写视图逻辑,可以通过请求对象获取用户提交的数据,然后返回 HTTP 响应。
比较两者,CBV 提供了更多的面向对象特性和可重用性,因为它可以利用类的继承和方法重写来实现视图的复用。而 FBV 相对来说更加简单,适合处理简单的视图逻辑。
在 Django 中,你可以根据项目需求和个人偏好选择使用 CBV 或 FBV 来实现视图功能。
3、CBV视图函数的书写方式
class MyLogin(View):
# 类里面的方法名字不能够随便写,目前只能写get post等
# 访问这个地址必须是get请求方式
def get(self, request):
# get() takes 1 positional argument but 2 were given
print("get")
return HttpResponse("get")
# 访问这个方法必须是psot请求方式
# 通过form表单发送post请求
# 出了form表单,我们还可以使用工具来模拟
def post(self,request):
print("post")
return HttpResponse("post")
4、在postman中提交form表单测试
注意:url要加完整的路径,后面的/浏览器回自动添加,postman不会

1、看源码先找到源码的入口
path('login/', views.MyLogin.as_view()),
注:MyLogin是自定义的类(视图层)
MyLogin.as_view() 即类调用方法
类名可以调用哪些方法:
1. 方法被@classmethod装饰器修饰的方法
类名来调用类方法有什么特殊之处:
会把类名自动当成第一个参数传递给方法的第一个形参cls
2. 被@staticmethod装饰器修饰的方法
2、第一步
@classonlymethod
def as_view(cls, **initkwargs):
# cls:MyLogin
def view(request, *args, **kwargs):
self = cls(**initkwargs)
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
self.setup(request, *args, **kwargs)
if not hasattr(self, 'request'):
raise AttributeError(
"%s instance has no 'request' attribute. Did you override "
"setup() and forget to call super()?" % cls.__name__
)
return self.dispatch(request, *args, **kwargs)
return view
3、第二步
上一步 return 返回view
path('login/', View.view),
4、第三步
当请求来的时候,开始匹配路由login,就会调用View.view()
5、第四步
def view(request, *args, **kwargs):
# self = MyLogin(**initkwargs)
self = cls(**initkwargs)
"""
self: MyLogin()
"""
return self.dispatch(request, *args, **kwargs) # 这句话是最重要的
6、第五步
self.dispatch(request, *args, **kwargs)
7、第六步
找到了View类里面的dispatch方法
8、第七步
def dispatch(self, request, *args, **kwargs):
# getattr: 反射
# 反射
# getattr setattr delattr hasattr
# handler = getattr(self, 'get', self.http_method_not_allowed)
# handler = getattr(self, 'post', self.http_method_not_allowed)
# handler就是方法名,对象
# hander = get
# hander = post
# hander = self.http_method_not_allowed
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)
9、如何让我写的CBV类只支持get请求或者只支持post请求?
方法重写
class MyLogin(View):
http_method_names = ['get',]
# 类里面的方法名字不能够随便写,目前只能写get post等
# 访问这个地址必须是get请求方式
def get(self, request):
# get() takes 1 positional argument but 2 were given
print("get")
return HttpResponse("get")
模板过滤器是一种用于在模板中对数据进行处理和格式化的工具。它们以管道符(|)后跟过滤器名的形式出现,用于对模板变量进行修改或转换。
过滤器能够帮助你在模板中进行一些简单的数据处理,例如格式化日期、字符串截断、转换大小写等。
1、
模板中取值一定使用的是句点符.
模板中的函数一定不能够加括号,他们会自动帮你加括号调用
# views
def func(request):
d = {'username': 'zjz', 'age': 18, 'hobby': ['喝酒', '抽烟', '打牌']}
def index():
return ('from index')
return render(request, 'temp.html', context=locals())
# html文件
<div>
<p>
{{ d.hobby.1 }} # 1是列表的下标
{{ index }}
</p>
</div>
2、
语法:
{{ obj | 过滤器名称:参数 }} 变量名字|过滤器名称:变量
date 过滤器:用于格式化日期。
<!-- 将日期对象格式化为 'Y年m月d日' 的形式 -->
{{ my_date_variable|date:'Y-m-d' }}
default 过滤器:在变量值不存在时,使用默认值。
<!-- 如果 my_variable 不存在,将显示 "Not available" -->
{{ my_variable|default:"Not available" }}
length 过滤器:获取列表或字符串的长度。
<!-- 显示 my_list 列表的长度 -->
{{ my_list|length }}
truncatechars 过滤器:截断字符串到指定长度,并在末尾添加省略号。
<!-- 将 my_string 截断到30个字符,并添加省略号 -->
{{ my_string|truncatechars:30 }}
lower 和 upper 过滤器:将字符串转换为小写或大写。
<!-- 将 my_string 转换为小写 -->
{{ my_string|lower }}
<!-- 将 my_string 转换为大写 -->
{{ my_string|upper }}
slice 过滤器:对列表进行切片。
<!-- 获取 my_list 列表的前5个元素 -->
{{ my_list|slice:":5" }}
<!-- 获取 my_list 列表的第2到第5个元素 -->
{{ my_list|slice:"1:5" }}
3、模版之标签
相比于模板中的变量,标签更为复杂一些,如
1、一些标签用来在输出中创建文本 2、一些标签用来进行流程控制(执行循环或者if判断) 3、一些标签用来将外部信息加载到模板中以供以后的变量使用
模板中的标签的格式为
# 1、
{% 标签名 %}
# 2、大多数标签都需要接收参数
{% 标签名 参数1 参数2 %}
# 3、一些标签需要有开始{% tag %}和结束标记{% endtag %}
{% 标签名 %}
...内容...
{% end标签名 %}
常用标签之for标签
#1、遍历每一个元素:
{% for person in person_list %}
<p>{{ person.name }}</p>
{% endfor %}
#2、可以利用{% for obj in list reversed %}反向循环。
#3、遍历一个字典:
{% for key,val in dic.items %}
<p>{{ key }}:{{ val }}</p>
{% endfor %}
#4、循环序号可以通过{{ forloop }}显示
forloop.counter 当前循环的索引值(从1开始)
forloop.counter0 当前循环的索引值(从0开始)
forloop.revcounter 当前循环的倒序索引值(从1开始)
forloop.revcounter0 当前循环的倒序索引值(从0开始)
forloop.first 当前循环是第一次循环则返回True,否则返回False
forloop.last 当前循环是最后一次循环则返回True,否则返回False
forloop.parentloop 本层循环的外层循环
#5、for标签可以带有一个可选的{% empty %} 从句,在变量person_list为空或者没有被找到时,则执行empty子句
{% for person in person_list %}
<p>{{ person.name }}</p>
{% empty %}
<p>sorry,no person here</p>
{% endfor %}
了解:Django框架的for循环,没有break和continue方法,可以使用自定义过滤器实现forloop | continue和forloop | break,参考:https://djangosnippets.org/snippets/2093/
常用标签之if标签
# 1、注意:
{% if 条件 %}条件为真时if的子句才会生效,条件也可以是一个变量,if会对变量进行求值,在变量值为空、或者视图没有为其传值的情况下均为False
# 2、具体语法
{% if num > 100 or num < 0 %}
<p>无效</p>
{% elif num > 80 and num < 100 %}
<p>优秀</p>
{% else %}
<p>凑活吧</p>
{% endif %}
#3、if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。
#4、判断条件中可以引入过滤器
{% if athlete_list|length > 1 %}
Team: {% for athlete in athlete_list %} ... {% endfor %}
{% else %}
Athlete: {{ athlete_list.0.name }}
{% endif %}
过滤器length返回的数字可用于与数字进行比较,除此之外大多数过滤器返回的都是字符串并不能用于与数字比较
#5、补充标签firstof
针对下述多分支
{% if var1 %}
{{ var1 }}
{% elif var2 %}
{{ var2 }}
{% elif var3 %}
{{ var3 }}
{% endif %}
可以简写为一行
{% firstof var1 var2 var3 %}
也可以定义一个备用值,当var1、var2、var3均无值的时使用
{% firstof var1 var2 var3 "fallback value" %}
常用标签之with标签
d = {'username':'kevin','age':18,'info':'这个人有点意思','hobby':[111,222,333,{'info':'NB'}]}
{% with d.hobby.3.info as nb %}
<p>{{ nb }}</p>
在with语法内就可以通过as后面的别名快速的使用到前面非常复杂获取数据的方式
<p>{{ d.hobby.3.info }}</p>
{% endwith %}
常用标签之csrf_token标签
# 当用form表单提交POST请求时必须加上标签{% csrf_token%},该标签用于防止跨站伪造请求
<form action="" method="POST">
{% csrf_token %}
<p>用户名:<input type="text" name="name"></p>
<p>密码:<input type="password" name="pwd"></p>
<p><input type="submit" value="提交"></p>
</form>
# 具体工作原理为:
# 1、在GET请求到form表单时,标签{% csrf_token%}会被渲染成一个隐藏的input标签,该标签包含了由服务端生成的一串随机字符串,如<input type="hidden" name="csrfmiddlewaretoken" value="dmje28mFo...OvnZ5">
# 2、在使用form表单提交POST请求时,会提交上述随机字符串,服务端在接收到该POST请求时会对比该随机字符串,对比成功则处理该POST请求,否则拒绝,以此来确定客户端的身份
# ps:什么是跨站请求伪造(英语:Cross-site request forgery)详见附录2
继承:继承之后的页面跟被继承的页面一模一样
继承之后,要自己在基础html页面中划分要修改的区域,继承一方进行修改
1、关键字 extends
在子页面书写,xxx.html为父页面
{% extends 'xxx.html' %}
2、关键字 block
block可以包裹任意一个块,也可以是一个空的地方
content为某一个块的名字
{% block content %}
<h1>日子常新,未来可期!</h1>
<p>人间烟火,山河远阔,无一是你,无一不是你</p>
<p><a class="btn btn-primary btn-lg" href="#" role="button">诗和远方</a></p>
{% endblock %}
3、子页面为某一个标签设置css(js 也一样)
在主页面划分一个空的block,子页面中使用block写css
{% block css %}
{% endblock %}
4、模板的导入
在一个页面导入另一个页面
{% include 'hello.html' %}
5、bootstrap扣组件案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script>
</head>
<body>
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Brand</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-md-3">
<div class="list-group">
<a href="#" class="list-group-item active">
起点
</a>
<a href="/login/" class="list-group-item">登录</a>
<a href="/register/" class="list-group-item">注册</a>
<a href="/bq/" class="list-group-item">回原点</a>
</div>
</div>
<div class="col-md-9">
<div class="panel panel-primary">
<div class="panel-heading">Panel heading without title</div>
<div class="panel-body">
<div class="jumbotron">
{% block content %}
<h1>永远十八,永远热泪盈眶!</h1>
<p>人间烟火,山河远阔,无一是你,无一不是你</p>
<p><a class="btn btn-primary btn-lg" href="#" role="button">诗和远方</a></p>
{% endblock %}
<div class="row">
<div class="col-sm-6 col-md-4">
<div class="thumbnail">
<img src="https://th.bing.com/th/id/R.1363fff14ac660729966b15ed3ad0613?rik=Clu%2bvv4ZhfF3xA&riu=http%3a%2f%2fimg.ts.cn%2f003%2f523%2f914%2f00352391449_110e6504.jpg&ehk=pAoDU5Z5PM%2bAGGTi%2fjFpRneEpsghtBugLhmPAgZ%2fYMg%3d&risl=&pid=ImgRaw&r=0"
alt="...">
<div class="caption">
<h3>海棠未雨</h3>
<p>...</p>
<p><a href="#" class="btn btn-primary" role="button">Button</a> <a href="#"
class="btn btn-default"
role="button">Button</a>
</p>
</div>
</div>
</div>
<div class="col-sm-6 col-md-4">
<div class="thumbnail">
<img src="https://th.bing.com/th/id/R.373fa8856674ed20fdbcc32548f907b4?rik=Xm0QJfBfZEhuDQ&riu=http%3a%2f%2fimg.mp.itc.cn%2fupload%2f20160908%2f9856d4f910aa40588853e64d5123521d_th.jpg&ehk=HCDdYJ5YRQTkxi4wiVKU36n9ssllHBEE0qyZrk9y%2bwo%3d&risl=&pid=ImgRaw&r=0"
alt="...">
<div class="caption">
<h3>梨花先雪</h3>
<p>...</p>
<p><a href="#" class="btn btn-primary" role="button">Button</a> <a href="#"
class="btn btn-default"
role="button">Button</a>
</p>
</div>
</div>
</div>
<div class="col-sm-6 col-md-4">
<div class="thumbnail">
<img src="https://image.scol.com.cn/data/attachment/forum/202006/22/162921a691l373kgvlgqkb.jpg"
alt="...">
<div class="caption">
<h3>一半春休</h3>
<p>...</p>
<p><a href="#" class="btn btn-primary" role="button">Button</a> <a href="#"
class="btn btn-default"
role="button">Button</a>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>


浙公网安备 33010602011771号