• 开发工程师必备————【Day26】Django补充(三)


    今日内容详细

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

    网页伪静态

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

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

    视图层

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

    class HttpResponse(HttpResponseBase):
    	pass
    
    • 1
    • 2
    def render():
    	return HttpResponse(...)
    
    • 1
    • 2
    def redirect(to, *args, permanent=False, **kwargs):
    redirect_class = HttpResponsePermanentRedirect if permanent else HttpResponseRedirect
    	return redirect_class(resolve_url(to, *args, **kwargs))
    
    • 1
    • 2
    • 3

    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 引出JsonResponse方法
    def index(request):
      user_dict = {'name':'jason老师','pwd':123,'hobby':['read','run','music']}
      return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False})
    
    • 1
    • 2
    • 3

    推导方法如下:

    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)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 序列化非字典类型的数据还需要指定safe参数为False
     return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False},safe=False)
    
    • 1

    3.form表单携带文件数据

    • 前端需要:form表单需要具备的条件
    1)method属性值必须是post
    (2)enctype属性值必须是multipart/form-data
    
    <form action="" method="post" enctype="multipart/form-data">
    
    • 1
    • 2
    • 3
    • 4
    • 前端完整代码
    <!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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 后端获取文件数据的操作
    request.FILES
    
    • 1
    • 后端完整代码
    def index(request):
    	    if request.method == 'POST':
           print(request.POST)     # 
           print(request.FILES)    # ]}>
           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')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    4.FBV与CBV

    • FBV:基于函数的视图
    def index(request):
       return HttpResponse()
    path('index/', views.index)
    
    • 1
    • 2
    • 3
    • 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())
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

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

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

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

    源码分析步骤

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

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

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

    模板层

    1.模板语法传值

    • 方式1:指名道姓 指名道姓传参 不浪费资源
    def modal(request):
       # 方式一:指名道姓的传
       name = 'jason'
       return render(request,'modal.html',{'name':name})
    
    • 1
    • 2
    • 3
    • 4
    • 方式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())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    后端语法转义:

    from django.utils.safestring import mark_safe
       script_tag1 = ''
       res = mark_safe(script_tag1)
    
    • 1
    • 2
    • 3

    ps:有时候html页面上的数据不一定非要在html页面上编写了 也可以后端写好传入。

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

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

    • 支持if判断:
    条件一般为后端传来的值;直接写名字使用即可。
    
    语法结构:
    {% if 条件 %}  
    	条件成立执行的代码
    {% elif 条件1 %}
    	条件1成立执行的代码	
    {% else %}
    	条件都不成立执行的代码
    {% endif %}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 支持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 %}   
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • with(定义一个中间变量,多用于一个复杂的变量起别名。)
    语法结构:
    {% with d.others.1b.2 as aaa %}
    	{{aaa}}
    {% endwith %}
    
    • 1
    • 2
    • 3
    • 4

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

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

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

    from django.template import Library
    register = Library()
    
    # 自定义过滤器
    @register.filter(name='myfilter')
    def my_add(a,b):
       return a+b
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    (3)自定义标签函数

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

    (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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
       {% load mytag %}
       {{ i|myfilter:1 }}
       {% mt 1 2 3 4 %}
       {% index 10 %}
    
    • 1
    • 2
    • 3
    • 4

    6.模板的继承

    语法结构:
    
    {% extends 'html文件名' %}
    {% block 名字 %}
       	模板内容
    {% endblock %}
    {% block 名字 %}
       	子板内容
    {% endblock %}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

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

    CSS:
    {% block css %}
    {% endblock %}
    
    content:
    {% block content %}
    {% endblock %}
    
    Js:
    {% block js %}
    {% endblock %}
    
    注意:子板中还可以使用母板的内容  {{ block.super }}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

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

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

    {% include 'menu.html' %}
    
    • 1
  • 相关阅读:
    [论文阅读] Curriculum Semi-supervised Segmentation
    自动化更新包文件--shell脚本
    基于PID算法下STM32控制的坡道行驶电动小车(含源码)
    争夺细分新赛道,哪十家企业「领跑」L4级自动驾驶域控制器?
    暑假加餐|有钱人和你想的不一样(第15天)+财富与金钱的秘密【干货】
    中企绕道突破封锁,防不胜防 | 百能云芯
    字节、字、双字 关系
    图计算的数据结构与计算效率
    UMA 2 - Unity Multipurpose Avatar☀️八.UMA内置实用Recipes插件
    Elasticsearch面试题
  • 原文地址:https://blog.csdn.net/DiligentGG/article/details/126715553