day04

网页伪静态

将动态网页伪装成静态网页,从而提升网页被搜索引擎收录的概率
案例:
    1.在urls.py中添加
        # 定义test函数,为了演示方便,直接在urls.py中添加函数了
        def test(request):
        from django.shortcuts import HttpResponse
        return HttpResponse('这是个伪静态')
        #添加路由
        在urlpatterns中添加path('test.html', test)
    2.浏览器输入http://127.0.0.1:8000/test.html
    	页面显示'这是个伪静态'

准备

1.创建Django项目day58,应用app01
2.settings.py中
	MIDDLEWARE中注释掉django.middleware.csrf.CsrfViewMiddleware
	TEMPLATES中修改'DIRS': [os.path.join(BASE_DIR, 'templates')],
3.配置静态文件
	1.手动在Django项目中创建static目录,并放置jquery和bootstrap文件
	2. settings.py中配置
        STATICFILES_DIRS = [
            os.path.join(BASE_DIR, 'static')
        ]

视图层

1.视图函数的返回值问题
	'''视图函数必须返回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))
        """入门三件套最后返回的都是HttpResponse对象"""
案例:
    1.urls.py中修改
        from app01 import views
        urlpatterns = [
        path('admin/', admin.site.urls),
        path('index/', views.index)
        ]
    2.views.py中添加
    	from django.shortcuts import render,HttpResponse,redirect
        def index(request):
            return None
    3.启动Django,浏览器输入 127.0.0.1:8000/index/ 结果会报错,如下所示:
    """The view app01.views.index didn't return an HttpResponse object. It returned None instead."""

JsonResponse

2.视图函数返回json格式数据
案例:
    1.views.py中修改
        import json
        def index(request):
            user_dict = {
                'name': 'jason老师',
                'pwd': 123,
                'hobby': ['read', 'run', 'music']
            }
            json_str = json.dumps(user_dict, ensure_ascii=False)# ensure_accii取消中文编码
            return HttpResponse(json_str)
	2.启动Django,浏览器输入 127.0.0.1:8000/index/
    	浏览器页面显示 json格式的 {"name": "jason老师", "pwd": 123, "hobby": ["read", "run", "music"]}
# Django里封装了个方法 JsonResponse
案例:
	1.views.py中修改
        from django.http import JsonResponse
        def index(request):
            user_dict = {
                'name': 'jason老师',
                'pwd': 123,
                'hobby': ['read', 'run', 'music']
            }
    		return JsonResponse(user_dict, json_dumps_params={'ensure_ascii': False})
	2.启动Django,浏览器输入 127.0.0.1:8000/index/
    	浏览器页面显示 json格式的 {"name": "jason老师", "pwd": 123, "hobby": ["read", "run", "music"]}
################################################################################
案例:
    1.views.py中修改
        from django.http import JsonResponse
        def index(request):
            user_list = [11, 22, 33, 44, 55, 66, 'jason老师']
            return JsonResponse(user_list, json_dumps_params={'ensure_ascii': False})
	2.启动Django,浏览器输入 127.0.0.1:8000/index/ 结果会报错
    	"""In order to allow non-dict objects to be serialized set the safe parameter to False."""
解决:
    """序列化非字典类型的数据还需要指定safe参数为False"""
    把index函数,添加safe=False,如下所示:
    return JsonResponse(user_list, json_dumps_params={'ensure_ascii': False}, safe=False)
	浏览器再次访问,显示正常 [11, 22, 33, 44, 55, 66, "jason老师"]

form表单发送文件

form携带文件数据
	1.method属性值必须是post
	2.enctype属性值必须是 multipart/form-data
后端获取文件数据的操作:
    print('文件数据', request.FILES)
    file_obj = request.FILES.get('file') # file来自form的name
    # request.FILES.getlist 获取所有文件;get默认是最后1个
    file_obj.name # 文件名
#案例:
    1.views.py中修改
    def index(request):
    if request.method == 'POST':
        print(request.POST)
    return render(request, 'index.html')
	2.templates中创建index.html
        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>Title</title>
            {% load static %}
            <script src="{% static 'jquery.js' %}"></script>
            <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
            <script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
        </head>
        <body>
        <form action="" method="post">
            <p>username:
                <input type="text" name="username">
            </p>
            <p>file:
                <input type="file" name="file">
            </p>
            <input type="submit" value="提交">
        </form>
        </body>
        </html>
	3.启动Django,浏览器输入 127.0.0.1:8000/index/ 输入'jason',选择文件 'test.txt',再提交,查看pychrm终端打印
    	<QueryDict: {'username': ['jason'], 'file': ['test.txt']}>
#修改:
    1.views.py中修改
        def index(request):
        if request.method == 'POST':
            print('普通数据', request.POST)
            print('文件数据', request.FILES)
        return render(request, 'index.html')
    2.templates中修改index.html
    	<form action="" method="post" enctype="multipart/form-data">
 	3.启动Django,浏览器输入 127.0.0.1:8000/index/ 输入'jason',选择文件 'test.txt',再提交,查看pychrm终端打印
        普通数据 <QueryDict: {'username': ['jason']}>
        文件数据 <MultiValueDict: {'file': [<InMemoryUploadedFile: test.txt (text/plain)>]}>
#进阶:
	1.views.py中修改
        def index(request):	
            if request.method == 'POST':
                print('普通数据', request.POST)
                print('文件数据', request.FILES)
                file_obj = request.FILES.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')
	3.启动Django,浏览器输入 127.0.0.1:8000/index/ 输入'jason',选择文件 'test.txt',再提交
    		就能实现浏览器上传文件到后端,在Django下生成test.txt文件

FBV与CBV

FBV:基于函数的视图
	1.在views.py中定义函数
	def index(request):
        return HttpResponse()
    2.在urls.py中添加FBV路由
    	path('index/', views.index),
CBV:基于类的视图
	1.在views.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方法')
	2.在urls.py中添加CBV路由
    	path('func/', views.MyView.as_view()),
	3.启动Django,浏览器输入 127.0.0.1:8000/func/
    """CBV会自动根据请求方式的不同匹配类中定义的方法并自动执行"""

CBV源码分析

源码分析入口
	path('func/', views.MyView.as_view()),
    pycharm中,ctrl按住,选择as_view点击,就可以调到底层源码
1.绑定给类的as_view方法
	def as_view(...):
        def view(...):
            pass
        return view
2.CBV路由匹配本质:跟FBV是一致的
	变成了path('func/', views.view),
3.访问func触发view执行
	def view(...):
        obj = cls()
        return obj.dispatch()
    '''涉及到对象.名字 一定要确定对象是谁,再确定查找顺序'''
4.研究dispatch方法
	def dispatch(...):
        func_name = getattr(obj,request.method.lower())
        func_name(...)

模板语法传值

方式1:指名道姓 # 通过字典,精确,不浪费资源;但是数据多的时候,字典会很长
案例:
    1.在urls.py中添加路由
        # 模板层
        path('modal/', views.modal),
	2.在templates中创建空的modal.html文件
    3.在views.py中添加
        def modal(request):
            name = 'jason'
            age = 18
            gender = 'male'
            return render(request, 'modal.html', {'name': name, 'age': age, 'gender': gender})
方式2:关键字 locals() # 将整个局部名称空间中的名字全部传入,简单快捷
	修改view.py
        def modal(request):
            name = 'jason'
            age = 18
            gender = 'male'
            return render(request, 'modal.html', locals())

模板语法传值特性

# 基本数据类型直接传递使用
	"""Django的模板语法在操作容器类型的时候只允许使用句点符"""
案例:
    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', locals())
	2.在templates中修改modal.html文件
            <body>
                <p>{{ i }} </p>
                <p>{{ f }} </p>
                <p>{{ s }} </p>
                <p>{{ l }} </p>
                <p>{{ l.2 }} </p>
                <p>{{ d }} </p>
                <p>{{ d.name }} </p>
                <p>{{ d.others.1.b.2 }} </p>
                <p>{{ t }} </p>
                <p>{{ se }} </p>
                <p>{{ b }} </p>
            </body>
	# 可以使用多个句点符去选择,'{{ d.others.1.b.2 }}',结果是333
	3.启动Django,浏览器访问http://127.0.0.1:8000/modal/ 

# 函数名的传递会自动加括号执行,并将返回值展示到页面
	"""注意函数如果有参数,则不会执行,也不会展示,模板语法不支持"""
案例:
    1.在views.py中修改
    def modal(request):
        def func1():
            print('哈哈哈')
            return ('你到底行不行')
        return render(request, 'modal.html', locals())
	2.在templates中修改modal.html文件
        <body>
            <p>{{ func1 }}</p>
        </body>
	3.启动Django,浏览器访问http://127.0.0.1:8000/modal/ 页面打印'你到底行不行' 

# 类名的传递也会自动加括号产生对象并展示到页面上
	'''对象的传递则直接使用即可'''
案例:
    1.在views.py中修改
        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()
            return render(request, 'modal.html', locals())
	2.在templates中修改modal.html文件
        <body>
            <p>{{ MyClass }}</p>
            <p>{{ obj }}</p>
            <p>{{ obj.get_cls }}</p>
            <p>{{ obj.get_func }}</p>
            <p>{{ obj.get_obj }}</p>
        </body>
	3.启动Django,浏览器访问http://127.0.0.1:8000/modal/ 页面打印
        <app01.views.modal.<locals>.MyClass object at 0x000001BB2D91BB90>
        <app01.views.modal.<locals>.MyClass object at 0x000001BB2DA82C90>
        cls
        func
        obj
'''模板语法会判断每一个名字是否可以调用,如果可以则调用'''

模板语法过滤器

# 类似于Python的内置函数
案例:
    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
            from datetime import datetime
            res = datetime.today()
            file_size = 21432131  # 一般使用os.path.getsize() 单位是字节
            s1 = 'my name is jason my age is 18 hahaha heiheihei hehehe'
            script_tag = '<h1>还认识我吗</h1>' # 默认是传什么,就打印什么,不会变成h1样式
            from django.utils.safestring import mark_safe
            res1 = mark_safe('<h1>还认识我吗</h1>') # 后端也可以用这个模块实现safe
            '''html页面上的数据不一定非要在html页面上编写,也可以后端写好传入'''
            return render(request, 'modal.html', locals())
	2.在templates中修改modal.html文件
        <body>
            <p>统计长度:{{ s|length }}</p>
            <p>加法运算:{{ i|add:123 }},字符加法运算:{{ s|add:'heiheihei' }}</p>
            <p>转换时间:{{ res|date:'Y-m-d H:i:s' }}</p>
            <p>文件大小:{{ file_size|filesizeformat }}</p>
            <p>数据切片:{{ l|slice:'0:2' }}</p>
            <p>字符截取前6个:"{{ s1|truncatechars:6 }}</p>
            <p>单词截取(空格)前6个:"{{ s1|truncatewords:6 }}</p>
            <p>语法转义:{{ script_tag|safe }}</p>
            <p>{{ res1 }}</p>
        </body>
	3.启动Django,浏览器访问http://127.0.0.1:8000/modal/ 页面打印
"""
	Django模板语法中的符号就两个,一个{{ }},一个{% %}
	需要使用数据的时候 {{ }}
	需要使用方法的时候 {% %}
"""

模板语法标签

# 类似于Python流程控制
在templates中修改html文件,条件一般是模板语法传过来的数据,直接写名字即可
# if判断
    {% if 条件 %}
        条件成立执行的代码
    {% elif 条件1 %}
        条件1成立执行的代码
    {% else %}
        条件都不成立执行的代码
    {% endif %}
# for循环
    {% for i in l %}
        {% if forloop.first %}
            <p>这是第一次哦</p>
        {% elif forloop.last %}
            <p>这是最后异常哦</p>
        {% else %}
            <p>{{ i }}</p>
        {% endif %}
    {% empty %}
        <p>空的,怎么for循环</p>
    {% endfor %}
# 别名 给d.others.1.b.2起一个aaa的别名,在里面可以随意调用
    {% with d.others.1.b.2 as aaa %}
        {{ aaa }}
    {% endwith %}

# 目前先了解,之前Django的settings.py要注释MIDDLEWARE中注释掉django.middleware.csrf.CsrfViewMiddleware
# 在form表单里增加这个,跨域访问保护,产生token值.
{% csrf_token %}

模板自定义相关

"""
	如果想自定义 必须先做以下三件事
		1.在应用下创建名为templatetags文件夹
		2.在该文件夹创建容易名称的py文件
		3.在该py文件内编写自定义相关代码
"""
# 自定义过滤器,最多只能有2个参数
案例:
    1.应用app01下创建templatetags文件夹
    2.该文件夹下创建mytag.py文件
        from django.template import Library
        register = Library()
        @register.filter(name='myfilter')
        def my_add(a, b):
            return a + b # 简单的a+b
	3.templates的modal.html修改body
        <body>
            {% load mytag %}
            {{ i|myfilter:1 }}
        </body>
	4.启动Django,浏览器访问http://127.0.0.1:8000/modal/ 页面打印

# 自定义标签函数,可以传多个参数,*args
案例:
    1.mytag.py文件添加
        @register.simple_tag(name='mt')
        def func(a, b, c, d):
            return a + b + c + d
	2.templates的modal.html修改body
        <body>
            {% load mytag %}
            {% mt 1 2 3 4 %}
        </body>
	4.启动Django,浏览器访问http://127.0.0.1:8000/modal/ 页面打印
# 自定义inclusion_tag
案例:
    1.mytag.py文件添加
        @register.inclusion_tag(filename='it.html')
        def index(n):
            html = []
            for i in range(n):
                html.append('第%s页' % i)
            return locals()
	2.templates中创建it.html #不是完整的html.就只有ul
        <ul>
            {% for i in html %}
                <li>{{ i }}</li>
            {% endfor %}
        </ul>
	3.templates的modal.html修改body
        {%  index 10 %}
        {%  index 5 %}
	4.启动Django,浏览器访问http://127.0.0.1:8000/modal/ 页面打印
		#会根据index后面的数字,找到it.html插入到modal.html中;数字是几,就插入几次.

模板继承

"""在templates中创建子版html文件"""
    {% extends '母版html文件名' %}
        {% block 名字 %}
            替换内容
        {% endblock %}
"""在template中修改母板html文件"""
        {% block 名字 %}
            模板内容
        {% endblock %}
'''补充 {{ block.super }} 可以在子版里继承母板,使用母版的内容'''
一般情况母版里有三个区域要加,扩展性更高
	css content js # 子版可以替换自己的样式和脚本以及内容
案例:
	1.在urls.py中添加路由
        path('home/', views.home),
        path('register/', views.register),
        path('login/', views.login),
	2.templates中创建home文件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    {% load static %}
    <script src="{% static 'jquery.js' %}"></script>
    <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
    <script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
    {% block css %}
    
    {% endblock %}
</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="/home/" class="list-group-item active">
                    首页
                </a>
                <a href="/login/" class="list-group-item">登录</a>
                <a href="/register/" class="list-group-item">注册</a>
                <a href="#" class="list-group-item">更多</a>
                <a href="#" class="list-group-item">外链</a>
            </div>
        </div>
        <div class="col-md-9">
            <div class="panel panel-primary">
                <div class="panel-heading">
                    <h3 class="panel-title">Panel title</h3>
                </div>
                <div class="panel-body">
                    {% block content %}
{#                        {% include 'menu.html' %}#}
                        <div class="jumbotron">
                        <h1>全世界最大的线上学习平台!</h1>
                        <p>...</p>
                        <p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
                    </div>
                    {% endblock %}
                </div>
            </div>
        </div>
    </div>
</div>
{% block js %}

{% endblock %}
</body>
</html> 
	3.template中创建子版html文件
    # register.html文件
        {% extends 'home.html' %}

        {% block css %}
        <style>
            h1 {
                color: red;
            }
        </style>
        {% endblock %}

        {% block content %}
        <h1 class="text-center">注册页面</h1>
        <form action="">
            <p>username:<input type="text" class="form-control"></p>
            <p>password:<input type="text" class="form-control"></p>
    		{{ block.super }}
            <input type="submit" class="btn btn-primary btn-block">
        </form>
        {% endblock %}

        {% block js %}
        <script>
            alert('注册页面独有的脚本')
        </script>
        {% endblock %}
    # login.html文件
        {% extends 'home.html' %}

        {% block css %}
            <style>
                h1 {
                    color: orange;
                }
            </style>
        {% endblock %}

        {% block content %}
            <h1 class="text-center">登录页面</h1>
            <form action="">
                <p>username:<input type="text" class="form-control"></p>
                <p>password:<input type="text" class="form-control"></p>
                <input type="submit" class="btn btn-danger btn-block">
            </form>
        {% endblock %}

        {% block js %}
            <script>confirm('下午不要困')</script>
        {% endblock %}  
	4.启动Django,浏览器访问http://127.0.0.1:8000/home/ 点击登录和注册,查看页面

模板导入(了解)

将html页面当做模块的形式导入使用
	{% include '模块html文件' %}
案例:
    1.template中创建模块html文件
        # menu.html文件
        <h1>我是一个非常好看的form表单</h1>
	2.调用该模板html,例如,register.html导入改模板html
    	'''在register.html中添加include'''
        <form action="">
            <p>username:<input type="text" class="form-control"></p>
            <p>password:<input type="text" class="form-control"></p>
            {% include 'menu.html' %}
            {{ block.super }}
            <input type="submit" class="btn btn-primary btn-block">
        </form>
	3.启动Django,浏览器访问http://127.0.0.1:8000/home/ 点击注册,查看页面,多了'我是一个非常好看的form表单'

本文作者:ycmyay

本文链接:https://www.cnblogs.com/ycmyay/p/17383807.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   也曾滿眼愛意丶  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
🔑