网页伪静态
将动态网页伪装成静态网页 从而提升网页被搜索引擎的概率
表现形式就是网址看着像一个具体的文件路径
path('index.html',view.index)
视图层
一、视图函数的返回值问题
视图函数必须返回一个HttpResponse对象
研究码源发现HttpResponse其实是一个类
class HttpResponse(HttpResponseBase):
pass
def render():
return HttpResponse(...)
def redirect(to, *args, permanent=False, **kwargs):
redirect_class = HttpResponsePermanentRedirect if permanent else HttpResponseRedirect
return redirect_class(resolve_url(to, *args, **kwargs))
二、视图函数返回的json格式数据
- 使用json模块
import json
def func(request):
user_dict = {'name': 'jason', 'pwd': 123, 'hobby': ['read', 'run', 'music']}
json_str = json.dumps(user_dict, ensure_ascii=False) # ensure_ascii=False显示中文,不设置此参数就会以二进制字节展示
return HttpResponse(json_str)
- 用django自带JsonResponse模块
from django.http import JsonResponse
def func(request):
user_dict = {'name': 'jason', 'pwd': 123, 'hobby': ['read', 'run', 'music']}
return JsonResponse(user_dict, json_dumps_params={'ensure_ascii':False}) # json_dumps_params={'ensure_ascii':False}显示中文
- 序列化非字典类型的数据还需要指定safe参数为False
from django.http import JsonResponse
def func(request):
user_hobby = ['read', 'run', 'music']
return JsonResponse(user_hobby, safe=False, json_dumps_params={'ensure_ascii':False}) # json_dumps_params={'ensure_ascii':False}显示中文
三、form表单携带文件数据
- form表单上传文件类型的数据
1.method必须指定成post
2.enctype属性值必须是multipart/form-data
"""
后端获取文件数据的操作
request.FILES
"""
def index(request):
if request.method == 'POST':
file_obj = request.FILES.get('file') # file就是我们在前端form表单下的input中name属性设置的名字
with open(file_obj.name, 'wb') as f: # file_obj.name就可以点出文件的名字
for line in file_obj:
f.write(line)
return render(request, 'index.html') # 还可以上传视频
# 前端代码
<form action="" method="post" enctype="multipart/form-data">
<p><input type="file" name="file"></p>
<p><input type="submit" value="提交"></p>
</form>
四、FBV与CBV
视图函数既可以是函数 也可以是类
- 1.FBV:基于函数的视图
# 视图
def index(request):
return HttpResponse()
# 路由
path('index/', views.index)
- 2.CBV:基于类的视图
# 视图
from django import views
class MyView(views.View):
def get(self, request):
return HttpResponse('我是CBV里面的get方法')
def post(self, request):
return HttpResponse('我是CBV里面的post方法')
# 路由
path('func/', views.MyView.as_view())
"""
CBV会自动根据请求方式的不同匹配类中定义的方法并自动执行
"""
五、CBV源码分析(重要)
# 突破口在urls.py
url(r'^login/',views.MyLogin.as_view())
# url(r'^login/',views.view) FBV一模一样
# CBV与FBV在路由匹配上本质是一样的 都是路由 对应 函数内存地址
"""
函数名/方法名 加括号执行优先级最高
猜测
as_view()
要么是被@staicmethod修饰的静态方法
要么是被@classmethod修饰的类方法 正确
@classonlymethod
def as_view(cls, **initkwargs):
pass
"""
@classonlymethod
def as_view(cls, **initkwargs):
"""
cls就是我们自己写的类 MyCBV
Main entry point for a request-response process.
"""
def view(request, *args, **kwargs):
self = cls(**initkwargs) # cls是我们自己写的类
# self = MyLogin(**initkwargs) 产生一个我们自己写的类的对象
return self.dispatch(request, *args, **kwargs)
"""
以后你们会经常需要看源码 但是在看python源码的时候 一定要时刻提醒自己面向对象属性方法查找顺序
先从对象自己找
再去产生对象的类里面找
之后再去父类找
...
总结:看源码只要看到了self点一个东西 一定要问你自己当前这个self到底是谁
"""
return view
# CBV的精髓
def dispatch(self, request, *args, **kwargs):
# 获取当前请求的小写格式 然后比对当前请求方式是否合法
# get请求为例
# post请求
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
"""
反射:通过字符串来操作对象的属性或者方法
handler = getattr(自己写的类产生的对象,'get',当找不到get属性或者方法的时候就会用第三个参数)
handler = 我们自己写的类里面的get方法
"""
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)
"""
自动调用get方法
"""
模板层
一、模板语法传值
- 方式一:指名道姓(指名道姓传参 不浪费资源)
'''
django模板语法中的符号就两个 一个{{}} 一个{%%}
需要使用数据的时候 {{}}
需要使用方法的时候 {%%}
'''
# 后端
name = 'jason'
return render(request, 'modal.html', {'name':name})
# 前端
{{ name }} # 可以直接使用后端name
- 方式二:关键字locals(将整个局部名称空间的名字全部传入 简单快捷)
# 后端
def func(request):
name = 'jason'
age = 18
hobby = 'read'
return render(request,'modal.html',locals())
# 前端
{{ name }} {{ age }} {{gender}} {{request}} # 后端有的都可以直接使用
二、模板语法传值的范围
1.python基本数据类型直接传递使用
2.函数名的传递会自动加括号执行并将返回值展示到页面上 没有返回值就是None
注意函数如果有参数则不会执行也不会展示 模板语法不支持有参函数
3.类名的传递也会自动加括号产生对象并展示到页面上
对象的传递则直接使用即可
ps:模板语法会判断每一个名字是否可调用 如果可以则调用!!!
"""
django的模板语法在操作容器类型的时候只允许使用句点符
"""
代码演示
# urls.py
path('test2/',views.test2)
# views.py
def aaa():
return 'aaa'
class Person:
def __init__(self):
pass
def test2(request):
p=Person # 类
p1=Person() # 对象
a=aaa # 函数名
return render(request,'test2.html',locals())
# html页面
<body>
<h3>{{ p }}</h3>
<h3>{{ p1 }}</h3>
<h3>{{ a }}</h3>
</body>
三、模板语法过滤器(类似于python内置函数)
import datetime
def filter1(request):
a='hello,world!'
b=10
c=datetime.datetime.today()
d=23232323232
e=[1,2,3,4,5,6]
f='my name is jason'
css_tag='<i>你好</i>'
script_tag='<script>alert(123)</script>'
# 语法转义第二种方式
from django.utils.safestring import mark_safe
res=mark_safe('<script>alert(333)</script>')
return render(request,'filter.html',locals())
<p>统计长度:{{ s|length }}</p> # 计算s的长度
<p>加法运算:{{ i|add:123 }}、加法运算:{{ s|add:'heiheihei' }}</p> # 加法运行 还支持字符串拼接
<p>日期转换:{{ s|date:'Y-m-d H:i:s' }}</p> # 将日期按照指定的格式展示
<p>文件大小:{{ file_size|filesizeformat }}</p> # 判断该文件的大小
<p>数据切片:{{ l|slice:'0:10' }}</p> # 将数据索引0到索引10进行切片 顾头不顾尾
<p>字符截取:{{ s1|truncatechars:6 }}</p> # 展示6个字节内容 三个点算一个
<p>单词截取(空格):{{ s1|truncatewords:6 }}</p>
<p>语法转义:{{ script_tag|safe }}</p>
<p>语法转义:{{ script_tag1|safe }}</p>
from django.utils.safestring import mark_safe
script_tag1 = '<script>alert(666)</script>'
res = mark_safe(script_tag1)
PS:有时候html页面上的数据不一定非要在html页面上编写了 也可以后端写好传入
四、模板语法标签(类似于python流程控制)
- if判断
{% if 条件 %} # 条件一般是模板语法传过来的数据 直接写名字使用即可
<h1>我是if</h1> # 条件成立执行的代码
{% elif 条件1 %}
<h1>我是elif</h1> # 条件1成立执行的代码
{% else %}
<h>我是else</h> # 条件都不成立执行的代码
{% endif %}
- for循环
{% for i in s %}
<p>{{ i }}</p>
{% endfor %
- for循环+if判断
{% for foo in lll %}
{% if forloop.first %}
<p>这是我的第一次</p>
{% elif forloop.last %}
<p>这是最后一次啊</p>
{% else %}
<p>{{ foo }}</p>
{% endif %}
{% empty %}
<p>for循环的可迭代对象内部没有元素 根本没法循环</p>
{% endfor %}
with起别名
{% with d.hobby.3.info as nb %}
<p>{{ nb }}</p>在with语法内就可以通过as后面的别名快速的使用到前面非常复杂获取数据的方式
<p>{{ d.hobby.3.info }}</p>
{% endwith %}
五、自定义标签函数、过滤器、inclusion_tag
如果想自定义 必须先做以下三件事
1.在应用下创建一个名为templatetags文件夹
2.在该文件夹创建任意名称的py文件
3.在该py文件内编写自定义相关代码
- 1.自定义过滤器
在templatetags文件夹创建一个mytag的py文件
from django.template import Library
register=Library()
@register.filter(name='myfilter')
def my_add(a, b):
return a + b
# 前端页面需要先导入mytag
{% load mytag %}
{{ i|myfilter:1 }}
- 2.自定义标签函数
@register.simple_tag(name='mt')
def func(a, b, c, d):
return a + b + c + d
# 使用
{% load mytag %}
{% mt 1 2 3 4 %}
- 3.自定义inclusion_tag
@register.inclusion_tag(filename='it.html')
def index(n):
html = []
for i in range(n):
html.append('第%s页'%i)
return locals()
# 使用
{% load mytag %}
{% index 10 %}
六、模板的继承
{% extends '要继承html文件名' %}
{% block 名字 %}
模板内容
{% endblock %}
{% block 名字 %}
子板内容
{% endblock %}
"""
一般情况下母板中至少应该有三个区域使得扩展性更高:css content js
"""
# css
{% block css %}
# css代码区
{% endblock %}
# content
{% block content %}
# 内容区
{% endblock %}
# js
{% block js %}
# js代码区
{% endblock %}
'''子板中还可以使用母板的内容 {{ block.super }} '''
七、模板的导入(了解)
将html页面的某个部分当做模块的形式导入使用
{% include '要导入的html文件' %}
posted on
浙公网安备 33010602011771号