开发工程师必备————【Day26】Django视图层与模板层

今日内容详细

  • 网页伪静态
  • 视图层
  • 模板层

网页伪静态

1.本质
将动态网页伪装成静态网页,从而提升网页被搜索引擎收录的概率。
2.表现形式
表现形式就是网址看着像一个具体的文件路径。

path('index.html',view.index)

视图层

1.视图函数的返回值问题
视图函数必须返回一个HttpResponse对象
注意HttpResonse其实是一个类

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))

2.视图函数返回json格式数据

  • 前戏之展示json存数据
def index(request):
   user_dict = {'name':'jason老师','pwd':123,'hobby':['read','run','music']}
   json_str = json.dumps(user_dict,ensure_ascii=False)
   return HttpResponse(json_str)
   return JsonResponse(user_dict)
  • 引出JsonResponse方法
def index(request):
  user_dict = {'name':'jason老师','pwd':123,'hobby':['read','run','music']}
  return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False})

推导方法如下:

from django.http import JsonResponse
class JsonResponse(HttpResponse):
def __init__(self, data, encoder=DjangoJSONEncoder, safe=True,
	json_dumps_params=None, **kwargs):
	 if json_dumps_params is None:
	 	json_dumps_params = {}
	data = json.dumps(data, cls=encoder, **json_dumps_params)

  • 序列化非字典类型的数据还需要指定safe参数为False
 return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False},safe=False)

3.form表单携带文件数据

  • 前端需要:form表单需要具备的条件
1)method属性值必须是post
(2)enctype属性值必须是multipart/form-data

<form action="" method="post" enctype="multipart/form-data">
  • 前端完整代码
<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Title</title>
   <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
   <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
   <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<form action="" method="post" enctype="multipart/form-data">
   <p>username:
       <input type="text" name="username">
   </p>
   <p>file:
       <input type="file" name="file">
   </p>
   <input type="submit" value="提交">
</form>
</body>
</html>
  • 后端获取文件数据的操作
request.FILES
  • 后端完整代码
def index(request):
	    if request.method == 'POST':
       print(request.POST)     # <QueryDict: {'username': ['jason']}>
       print(request.FILES)    # <MultiValueDict: {'file': [<InMemoryUploadedFile: 9.9.md (application/octet-stream)>]}>
       file_obj = request.FILES.get('file')
       print(file_obj.name)    # 9.9.md
       # 将文件保存到后端
       with open(file_obj.name,'wb')as f:
           for line in file_obj:   # 循环写入
               f.write(line)
   return render(request,'index.html')

4.FBV与CBV

  • FBV:基于函数的视图
def index(request):
   return HttpResponse()
path('index/', views.index)
  • CBV:基于类的视图
后端view.py文件:
from django import views
class MyView(views.View):
	def get(self, request):
		return HttpResponse('我是CBV里面的get方法')
	def post(self, request):
		return HttpResponse('我是CBV里面的post方法')

后端urls.py文件:
urlpatterns = [
# CBV路由匹配
	path('func/', views.MyView.as_view())
]

CBV会自动根据请求方式的不同匹配类中定义的方法并自动执行。

5.CBV源码分析(重要)
源码分析入口

path('func/', views.MyView.as_view())

源码分析步骤

  • 绑定给类的as_view方法
def as_view(...):
def view(...):
pass
return view
  • CBV路由匹配本质:跟FBV是一致的
path('func/', views.view)
  • 访问func触发view执行
def view(...):
obj = cls()
return obj.dispatch()

涉及到对象点名字,一定要确定对象是谁,再确定查找顺序!!!

  • 研究dispatch方法
def dispatch(...):
func_name = getattr(obj,request.method.lower())
func_name(...)

模板层

1.模板语法传值

  • 方式1:指名道姓 指名道姓传参 不浪费资源
def modal(request):
   # 方式一:指名道姓的传
   name = 'jason'
   return render(request,'modal.html',{'name':name})
  • 方式2:关键字locals() 将整个局部名称空间中的名字去全部传入简单快捷
def modal(request):
   name  = 'jason'
   age = 18
   gender = 'male'
   # return render(request,'modal.html',{'name':name,'age':age,'gender':gender})
   return render(request,'modal.html',locals())

2.模板语法传值的范围
django的模板语法在操作容器类型的时候只允许使用句点符

  • 基本数据类型(整型,浮点型,列表,字典,布尔值,元组,集合)直接传递使用;
  • 函数名的传递会自动加括号执行并将返回值展示到页面上;
    注意函数如果有参数则不会执行也不会展示,没有传参功能,模板语法不支持有参函数。
  • 类名的传递也会自动加括号产生对象并展示到页面上;
  • 对象的传递则直接使用即可
    ps:模板语法会判断每一个名字是否可调用 如果可以则调用!!!

3.模板语法过滤器(类似于python内置函数)

<p>统计长度:{{ s|length }}</p>
<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>
<p>字符截取(三个点算一个):{{ s1|truncatechars:6 }}</p>
<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页面上编写了 也可以后端写好传入。

  • django模板语法中的符号就两个,一个{{}}; 一个{%%}。
    (1)需要使用数据的时候 {{}}
    (2)需要使用方法的时候 {%%};包括流程控制,内置方法等。

4.模板语法标签(类似于python流程控制)

  • 支持if判断:
条件一般为后端传来的值;直接写名字使用即可。

语法结构:
{% if 条件 %}  
	条件成立执行的代码
{% elif 条件1 %}
	条件1成立执行的代码	
{% else %}
	条件都不成立执行的代码
{% endif %}
  • 支持for循环:
语法结构:
{% for i in s %}
	{% if forloop.first %}
		<p>这是第一次哟~</p>
	{% elif forloop.last %}
		<p>这是最后一次!</p>
	{% else %}
 		<p>{{ i }}</p>
	{% endif %}
	{% empty %}
  		<p>你给我的是个空 怎么for循环呢</p>
{% endfor %}   
  • with(定义一个中间变量,多用于一个复杂的变量起别名。)
语法结构:
{% with d.others.1b.2 as aaa %}
	{{aaa}}
{% endwith %}

5.自定义标签函数、过滤器、inclusion_tag
(1)如果想自定义 必须先做以下三件事:

  • 在应用下创建一个名为templatetags文件夹
  • 在该文件夹创建任意名称的py文件
  • 在该py文件内编写自定义相关代码
from django.template import Library
register = Library()

敲重点:自定义之后使用的时候需要在HTML页面先导入{% load 自定义内容 %}才能使用。
(2)自定义过滤器(过滤器最多只能有两个参数!!!)

from django.template import Library
register = Library()

# 自定义过滤器
@register.filter(name='myfilter')
def my_add(a,b):
   return a+b

(3)自定义标签函数

from django.template import Library
register = Library()
@register.simple_tag(name='mt')
def func(a, b, c, d):
	return a + b + c + d

(4)自定义inclusion_tag

from django.template import Library
register = Library()
@register.inclusion_tag(filename='it.html')
def index(n):
	html = []
	for i in range(n):
		html.append('第%s页'%i)
	return locals()
   {% load mytag %}
   {{ i|myfilter:1 }}
   {% mt 1 2 3 4 %}
   {% index 10 %}

6.模板的继承

语法结构:

{% extends 'html文件名' %}
{% block 名字 %}
   	模板内容
{% endblock %}
{% block 名字 %}
   	子板内容
{% endblock %}

一般情况下母板中至少应该有三个区域使得扩展性更高!!!
分别是css;content;js。

CSS:
{% block css %}
{% endblock %}

content:
{% block content %}
{% endblock %}

Js:
{% block js %}
{% endblock %}

注意:子板中还可以使用母板的内容  {{ block.super }}

扩展性更高,子板有自己的样式。

7.模板的导入(了解)
将html页面的某个部分当做模块的形式导入使用

{% include 'menu.html' %}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值