django4/网页伪静态/视图层/模板层

网页伪静态

动态页

动态网页,页面代码虽然没有变,但是显示的内容却是可以随着时间、环境或者数据库操作的结果而发生改变的。

静态页

即静态网页,是实际存在的,无需经过 服务器 的 编译 ,直接加载到客户 浏览器 上显示出来。

特点

1、静态网页每个网页都有一个固定的URL,且网页URL以.htm、.html、.shtml等常见形式为后缀,而不含有“?”。2、静态网页是实实在在保存在服务器上的文件,每个网页都是一个独立的文件。
3、静态网页的内容相对稳定,因此容易被搜索引擎检索;
-------------缺点--------------------------------------------------------------
4、静态网页没有数据库的支持,在网站制作和维护方面工作量较大,因此当网站信息量很大时完全依靠静态网页制作方式比较困难;
5、静态网页的交互性较差,在功能方面有较大的限制。
6、页面浏览速度迅速,过程无需连接数据库,开启页面速度快于动态页面。
7、减轻了服务器的负担,工作量减少,也就降低了数据库的成本。

伪静态页

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

-------------=--------------------
#路由层urls.py可以直接写一个。
path('index.html',view.index)

伪静态页的缺点

使用伪静态将占用一定量的CPU占有率,大量使用将导致CPU超负荷;
降低服务器访问承载量比如服务器能承载1000人,开启大量伪静态后,三百人。

视图层

每新添加一个功能都应该在路由文件 urls.py 中添加一个路由与视图的对应关系(请求路径的时候才有对应的 视图函数/类 去处理)
最简单的步骤:
先创建app
配置路由(路由与视图函数的对应关系)
写视图函数(要用到 HttpResponse, redirect,记得自己导过来)
编写模板页面

视图函数返回值


视图函数必须返回一个HttpResonse对象

HttpResponse

class HttpResponse(...):
      pass
    

render

def render(...):
      return HttpResponse(...)

redirect

def redirect(...):
      # 多继承

1.视图层返回值问题,必须返回一个什么?

当我们在视图层返回None,或者不返回时,页面报错,需要我们必须返回一个HttpResponse对象

小疑问?

那么视图层,三板斧中,除了返回HttpResponse我们比较觉得合理

返回的render和redirect为什么不报错呢?底层源码其实他俩调用的也是HttpResponse对象

from django.shortcuts import render, HttpResponse,redirect

#以下是部分源码
class HttpResponse(HttpResponseBase):
	pass
-----------render源码中也是返回的HttpResponseBase对象-------------------------------------
def render(request, template_name, context=None, content_type=None, status=None, using=None):
    """
    Return a HttpResponse whose content is filled with the result of calling
    django.template.loader.render_to_string() with the passed arguments.
    """
    content = loader.render_to_string(template_name, context, request, using=using)
    return HttpResponse(content, content_type, status)
----------------redirect源码中也是返回的HttpResponseBase对象---------------------------------------
def redirect(to, *args, permanent=False, **kwargs):
    redirect_class = HttpResponsePermanentRedirect if permanent else HttpResponseRedirect
        return redirect_class(resolve_url(to, *args, **kwargs))

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

小需求:不借助模板语法,视图层返回数据给浏览器,如图

image

两种方法

1.借助httpResponsejsondump

user_dict = {'name': 'lzl', 'pwd': 1111, 'hobby': ['read', 'music']}
json_str = json.dumps(user_dict, ensure_ascii=False)   #有中文的情况,把转码关闭掉。
return HttpResponse(json_str)

2.借助JsonResponse [用这个]

from django.http import  JsonResponse
def index(request):
    user_dict = {'name': 'lzl中文不转码', 'pwd': 1111, 'hobby': ['read', 'music']}
    return JsonResponse(user_dict)
return JsonResponse(user_dict, json_dumps_params={'ensure_ascii':False}) #中文不转码

如果想返回非字典类型数据
序列化非字典类型的数据还需要指定safe参数为False

from django.http import  JsonResponse
def index(request):
    l1 = [1,2,3,4,5,6,7,8,'lzl牛']
    return JsonResponse(l1, json_dumps_params={'ensure_ascii':False},safe = False)

JasonResponse是源码底层封装json

    def __init__(self, data, encoder=DjangoJSONEncoder, safe=True,
                 json_dumps_params=None, **kwargs):
        if safe and not isinstance(data, dict):
            raise TypeError(
                'In order to allow non-dict objects to be serialized set the '
                'safe parameter to False.'
            )
        if json_dumps_params is None:
            json_dumps_params = {}
        kwargs.setdefault('content_type', 'application/json')
        data = json.dumps(data, cls=encoder, **json_dumps_params)
        super().__init__(content=data, **kwargs)

3. form表单携带文件数据

小需求:浏览器上传文件数据,通过前端传给后端数据

1.前端form表单

2.后端

​ form表单需要具备的条件

​ 1.method 属性必须是post

​ 2.enctype属性必须是multipart/form-data

<form action="" method="post" enctype=multipart/form-data></form>

​ 3.后端获取文件数据的操作

​ request.FILES

#示例 获取
#v
file_obj = request.FILE.get('file')
print(file_obj.name)
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:基于函数的视图

CBV:基于类的视图


FBV示例

#urls.py路由层
from django import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/', view.index),
]
#views视图层
from django import views
def index(request):
	return HttpResponse()

CBV示例

#urls.py路由层
from django import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/', view.index),
    path('func/', views.MyView.as_view()),
    ]

#views视图层
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会自动根据请求方式的不同匹配类中定义的方法并自动执行

模板层

1.模板语法传值两种方式

方式1:指名道姓传参,不浪费资源,

def modal(request)
name = 'lzl'
return render(request,'modal.html',{'name':name})

方式二:关键字local() 将整个局部名称空间中的名字去全部 传入简单快捷

def modal(request)
name = 'lzl'
age = '18'
time = '7'
return  render(request,'modal.html',locals())

2.模板语法传值范围特性

1.基本数据类型(整型,浮点型,字符串,元组,列表)直接传递使用

#基本数据类型

#路由层
--------------------------------views.py--------------------------------------------
def modal(request):
    i = 123
    f = 11.11
    s = 'hello world'
    l = [11, 22, 33]
    d = {'name':'jason', 'pwd':123, 'others':[11, {'a':123, 'b':[111, 222, 333]},22]}
    t = (11, 22, 33)
    se = {11, 22, 33}
    b = True
   return render(request,'modal.html')
   
#模板层
-------------------------------modal.html--------------------------------------------
<!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>内容

{#    <p>{{ i }}</p>#}
{#    <p>{{ f }}</p>#}
{#    <p>{{ s }}</p>#}
{#    <p>{{ l }}</p>#}
{#    <p>{{ d }}</p>#}
{#    <p>{{ t }}</p>#}
{#    <p>{{ se }}</p>#}
{#    <p>{{ b }}</p>#}
{#    <p>{{ d.name }}</p>#}
{#    <p>{{ l.2 }}</p>#}
{#    <P>{{ d.others.1.b.2 }}</P>#}

2.函数名的传递会自动加括号执行并返回值展示到页面上

def modal(request):	
    def func1():
        print('哈哈哈')
         return '你到底行不行'
<p>{{ func1 }}</p>

------页面展示效果------------
你到底行不行

3.注意函数如果有参数则不会执行也不会展示,模板语法不支持有参函数

def modal(request):
    def func1(a,b):
        print('哈哈哈')
         return '你到底行不行'
<p>{{ func1 }}</p>

------页面不展示效果(模板语法不支持传参)------------

4.类名的传递也会自动加括号产生对象并展示到页面上

def modal(request):
	class MyClass(object):
        def get_obj(self):
            return 'obj'
        @classmethod
        def get_cls(cls):
            return 'cls'
        @staticmethod
        def get_func():
            return 'func'
    obj = MyClass()
    
    
 ----------------模板层modal.html--------------------------------------------

#前端 body内容
<p>{{ MyClass }}</p>

#名的传递也会自动加括号产生对象并展示到页面上
如果类调用打印对象
<p>{{ obj.get_obj }}</p>
<p>{{ obj.get_cls }}</p>
<p>{{ obj.get_func }}</p>

5.对象的传递则直接使用即可

#前端 body内容
<p>{{ obj }}</p>

ps:模板语法会判断每个名字是否可调用,如何可以则调用

注意!!!

django的模板语法在操作容器类型的时候只允许使用句点符

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

过滤器大概有五六十个,我们简单的罗列一些。

#路由层
--------------------------------views.py-------------------------
def modal(request):
    i = 123
    f = 11.11
    s = 'hello world'
    l = [11, 22, 33]
    d = {'name':'jason', 'pwd':123, 'others':[11, {'a':123, 'b':[111, 222, 333]},22]}
    t = (11, 22, 33)
    se = {11, 22, 33}
    b = True
    from datetime import datetime
    #日期
    res = datetime.today()
    #文件大小
    file_size = 214324322432344353234
    
   return render(request,'modal.html')
   =================modal.html==================================

 #模板层body内容
<p>统计长度:{{s|length}}</p>
<p></p>加法运算:{{i|add:123}}、加法运算:<p>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>单词截取(一个空格算一个)</p>

重点掌握过滤器

过滤器重点:语法转义

#为什么要加safe参数?

因为前端默认是不加载视图层的脚本标签语法的,如果默认加载,后果就是一旦后端写死循环弹出框,或者不友好的脚本,浏览器会直接崩溃,如果我们写的一定要加载,在后面跟上safe参数即可,告诉前端页面,此代码可以加载。

#视图层
-----------------------视图层view.py-------------------------

def modal(request):
    script_tag = '<h1>还认识我吗???</h1>'
    from django.utils.safestring import mark_safe
    script_tag1 = '<script>alert(666)</script>'
    res = mark_safe(script_tag1)
   return render(request,'modal.html')
   
----------------------前端模板层modal.html-------------------------------
#body内容
<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 模板语法中的符号就两个,一个{{}} 一个{%%}

需要使用数据的时候{{}},类似于上述的取值操作

需要使用方法的时候{%%},类似于之前的反向解析操作

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

以下是常用的,还有一些冷门的了解

#body内容
	{% if 条件 %}  条件一般是模板语法传过来的数据  直接写名字使用即可
        条件成立执行的代码
    {% elif 条件1 %}
 		  条件1成立执行的代码	
    {% else %}
       	 条件都不成立执行的代码
    {% endif %}
    {% for i in s %}
        {% if forloop.first %}
            <p>这是第一次哟~</p>
        {% elif forloop.last %}
            <p>这是最后一次!</p>
        {% else %}
            <p>{{ i }}</p>
        {% endif %}
        {% empty %}
        	  <p>你给我的是个空 怎么for循环呢</p>
    {% endfor %}

5.自定义相关功能(了解)

一般写全栈的时候会用到。

1.标签函数,

2,过滤器

3.inclusion_tag


如果想自定义 必须先做以下三件事
​ 1.在应用下创建一个名为templatetags文件夹(文件夹名字必须为templatetags)
​ 2.在该文件夹创建任意名称的py文件
​ 3.在该py文件内编写自定义相关代码

​ from django.template import Library
​ register = Library()

# 自定义过滤器
    @register.filter(name='myfilter')
    def my_add(a, b):
        return a + b
---------------------------------------------------- ----------- 	
    # 自定义标签函数
    @register.simple_tag(name='mt')
    def func(a, b, c, d):
        return a + b + c + d
-------------------------------------------------------------   	
    # 自定义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 %}
    {{ i|myfilter:1 }}
    {% mt 1 2 3 4 %}
    {% index 10 %}

6.模板的继承

1.模板的继承作用?

	为了减少代码的编写

2.使用方法

#主模板调用
	{% block 名字 %}
    	模板内容
	{% endblock %}

2.把字模板html文件内容清理

3.调用继承文件

#字模板调用
{% etends 'html文件名' %}

4.子板内容修改

{% block 名字 %}
    	子板内容
    {% endblock %}

一般情况下母板中至少应该有三个区域使得扩展性更高!!!

css

content

js

-------#css---------------------------------
    {% block css %}
	{% endblock %}

-------#content---------------------------
	{% block content %}
	{% endblock %}
	
	----#js-----------------
	{% block js %}
	{% endblock %}
'''子板中还可以使用母板的内容  {{ block.super }} '''

7.模板的导入(了解)

​ 将html页面的某个部分当做模块的形式导入使用

	{% include 'menu.html' %}
posted @ 2022-09-04 17:01  名字长的像一只老山羊  阅读(85)  评论(0编辑  收藏  举报