4.Django 模板语法

文章目录

      • 1. FBV与CBV
        • 1.1 FBV
        • 1.2 CBV
        • 1.3 CBV源码解析
          • 1.启动程序时
          • 2.请求来的时候
      • 2. 模板层
        • 2.1 模板语法
        • 2.2 测试环境
          • 1. 路由层
          • 2. 视图层
          • 3.前端页面
        • 2.3 基本数据类型传递
        • 2.4 传递函数结果
      • 3. 过滤器
        • 3.1 常见过滤器
          • 1. 统计长度
          • 2.默认值
          • 3.文件大小
          • 4.日期格式
          • 5.切片操作
          • 6.切取字符
          • 7.切取单词
          • 8.移除特定的字符
          • 9.拼接操作
          • 10.加法
          • 11.前端转义
      • 4. 标签
        • 4.1 for循环
        • 4.2 forloop 参数
        • 4.3 if判断
        • 4.4 for 与 if 混用
        • 4.5 empty
        • 4.6 for遍历字典
        • 4.7 with起别名
      • 5. 自定义模板语法
        • 5.1 过滤器
        • 5.2 标签
        • 5.3 inclusion_tag
      • 6. 继承模板
      • 7. 继承模板案例
        • 7.1 路由层
        • 7.2 视图层
        • 7.3 模板页面
        • 7.4 继承模板
        • 7.5 注册页面
        • 7.6 登入界面
      • 8. 导入模板

1. FBV与CBV

FBV(基于函数的视图)
CBV(基于类的视图)
Python 是一个门面向对象的编程语言。如果我们只用函数来编写视图函数,
那么就会造成很多面向对象的优点无法利用起来,比如说封装、继承、多态等

1.1 FBV

FBV 基于函数的视图
在views.py视图中中定义函数来处理用户请求,
函数中再定义如果是GET请求怎么处理,POST请求怎么处理...
0. 新建一个项目,解决template文件夹路径错误,注释中间件.
1. 项目路由层
2. app01视图函数
# 项目的路由层
from django.conf.urls import url
from django.contrib import admin
# 0. 导入 数图函数
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    # 1. FBV 方式
    url(r'^register/', views.register),
]
# app01 的视图层
# 0. 导入Python 三板斧
from django.shortcuts import render, HttpResponse, redirect

# 1.定义函数
def register(request):
    # 写逻辑
    return HttpResponse('index页面')

1.2 CBV

CBV 基于类的视图
体现了Python面向对象这一语言特性。CBV 是通过类的方式来编写视图函数.
这相比较于函数,更能利用面向对象中多态的特性,因此更容易将项目中比较通用的功能抽象出来。
* urls.py文件中CBV的书写方式  类名.as_view() 方式映射,
定义的类需要继承 View ,
定义的方法按照固定样式,View类中支持以下方法:
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
CBV的特点:能根据不同的请求方式匹配对应的方法执行。
0. 项目路由层
1. app01视图函数
2. template 目录下创建 login.html
    # 项目的路由层
    # 2. CBV 方式
    url(r'^login/', views.Login.as_view())
# 2. 导入 View 类
from django.views import View


# 3.定义类
class Login(View):
    def get(self, request):
        return render(request, 'login.html')

    def post(self, request):
        return HttpResponse('Login页面 POST 请求')


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登入页面title>
head>
<body>
    <div>
        <form action="" method="post">
            <input type="submit">
        form>
    div>
body>
html>

4.Django 模板语法_第1张图片

3. 在浏览器中输入: 127.0.0.1:8000/login
4. 点提交

4.Django 模板语法_第2张图片

1.3 CBV源码解析

1.启动程序时

4.Django 模板语法_第3张图片

函数名,方法名加括号执行优先级最高。
在启动 Django 时就会执行 views.mylogin.as_view()

Login是类名,类使用.as_view()

查看源代码可以得知 结果就是 views.view

url('^login/', views.Login.as_view()) 
变形为 url('^login/', views.view), 

CBV和FBV在路由上本质是一样的,都是路由对应函数内置地址。 

在输入127.0.0.1:8000/login时触发 views.view
2.请求来的时候
getattr 反射:通过字符串来操作对象的属性或者方法
getattr(自己写的类对象,'小写的请求方式get/post',当找不这个小写的请求时才使用第三个参数)

不要修改源码,出现bug难查找。
在查看源码的时候一定要时刻提醒自己面对对象属性方法的查找顺序。
在查看源码时看到self.东西,一定要问自己当前这个self是谁
1. 先从自己的对象中找
2. 再去产生对象的类中查找
3. 父类中查找
# 源码
class View(object):
	# http的方法名字
    http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
	
    # View加括号的时候执行
    def __init__(self, **kwargs):
		# 遍历 kwargs 关键字参数, 通过setattr(对象, 属性, 值)设置默认值
        for key, value in six.iteritems(kwargs):
            setattr(self, key, value)
	
    # 静态方法
    @classonlymethod
    def as_view(cls, **initkwargs):
		# 关键字参数是否符合要求, 不符合就 raise 抛出错误.
        for key in initkwargs:
            #  关键字参数的变量名必须是 http的方法列表中的其中一个
            if key in cls.http_method_names:
                raise TypeError("You tried to pass in the %s method name as a "
                                "keyword argument to %s(). Don't do that."
                                % (key, cls.__name__))
            # hasattr(cls-->类名, 关键字参数的变量名) 函数用于判断对象是否包含对应的属性。    
            if not hasattr(cls, key):
                raise TypeError("%s() received an invalid keyword %r. as_view "
                                "only accepts arguments that are already "
                                "attributes of the class." % (cls.__name__, key))

        def view(request, *args, **kwargs):
            # self = Login(**initkwargs)
            self = cls(**initkwargs)
            # 当对象中有get属性 and 没有 head 属性的时候,   get 赋值给 head
            if hasattr(self, 'get') and not hasattr(self, 'head'):
                self.head = self.get
            # 对象.request 接收  request
            self.request = request
            # 对象.args 接收位置参数
            self.args = args
            # 对象.kwargs 接收关键字参数
            self.kwargs = kwargs
            # 返回 对象.dispatch()函数
            return self.dispatch(request, *args, **kwargs)
        """
        其他的不看了
        """
        return view

    def dispatch(self, request, *args, **kwargs):
        """
        request.method.lower()  获取请求方式 转小写
        判断 请求是否在 http方法列表中
        如果 存在 则取 去自己写的类总找对应请求名字的方法 赋值 给 handler, 
        				自己没有写这个请求的方法就抛出异常
        如果不存在,就将抛出异常的代码 赋值 给 handler
        
      	执行handler  handler要么是自己写的请求方法 要么是请求不存在http方法列表中报错
        """
        if request.method.lower() in self.http_method_names:
            # 方法 =      获取    对象中   请求方法                如果没有就抛出错误
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
    		# 不存在抛出错误
            handler = self.http_method_not_allowed
        
        return handler(request, *args, **kwargs)
    """
    其他的不看了
    """

2. 模板层

2.1 模板语法

模板语法的书写方法:
{{ 变量名 }}  变量相关
{%  %}       逻辑相关 for循环等
基本的数据类型都可以传递给前端。

模板语法内部会自动判断当前的变量(函数名, 类名)是否可以加括号调用,
如果可以就会自定加括号执行。

传递函数名会自动加括号进行调用,传递的是返回值.
传递类名的时候也会自动加括号实例化,传递的是对象.

* 模板语法不支持函数传递额外的参数,如果函数带参数则不会执行这条模板语法语句。
Django模板语法的取值格式:
1. 句点符 .键取值
2. 可以点索引
3. 两者混合使用

2.2 测试环境

1. 路由层
	# 项目的urls.py
    # 4.索引
    url('^index/', views.index)
2. 视图层
# app01的views.py
# 4.index 模板语法测试
def index(request):
    # 返回index.html 页面
    return render(request, 'index.html')
3.前端页面
templates目录下创建index.html文件

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模板语法测试title>
head>
<body>
    <h1>模板语法测试h1>
    
body>
html>

4.Django 模板语法_第4张图片

2.3 基本数据类型传递

模板语法可以传入后端Python数据类型
整型, 浮点型 字符串, 列表, 元组, 字典, 集合, 布尔值
# app01 views.py
# 4.index 模板语法测试
def index(request):
    # 返回index.html 页面
    # 基本数据类
    int_ = 1
    float_ = 1.1
    str_ = 'hello'
    list_ = [1, 2]
    tuple_ = (1, 2)
    dict_ = {'k1': 'v1'}
    set_ = {1, 2}
    bool_ = True
    print(locals())
    return render(request, 'index.html', locals())


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模板语法测试title>
head>
<body>
    <h1>模板语法测试h1>
    
    {{ int_ }}
    {{ float_ }}
    {{ str_ }}
    {{ list_ }}
    {{ tuple_ }}
    {{ dict_ }}
    {{ set_ }}
    {{ bool_ }}
body>
html>

4.Django 模板语法_第5张图片

.键取值
索引取值
值可以使用方法.
# app01 views.py
# 4.index 模板语法测试
def index(request):
    # 返回index.html 页面
    # 索引 .键 取值
    str_ = 'hello'
    list_ = [1, 2]
    tuple_ = (1, 2)
    dict_ = {'k1': 'v1', 'k2': 'v2'}
    dir1 = {'name': ['you', {'小名': ['二狗子', '狗剩']}]}

    print(locals())
    return render(request, 'index.html', locals())


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模板语法测试title>
head>
<body>
    <h1>模板语法测试h1>
    

    <p> {{ str_.0 }} {{ str_.1 }} p>
    <p> {{ list_.0 }}  p>
    <p> {{ tuple_.0 }} p>
    <p> {{ dict_.keys }}  {{ dict_.values }} {{ dict_.k1 }}p>
    <p> {{ dir1.name.0 }} p>
    <p> {{ dir1.name.1.小名 }}p>
body>
html>

4.Django 模板语法_第6张图片

2.4 传递函数结果

# app01 views.py
# 4.index 模板语法测试
def index(request):
    def func1():
        return 'func1 的返回值'

    # 返回index.html 页面
    print(locals())
    return render(request, 'index.html', locals())

    <p> {{ func1 }} p>

4.Django 模板语法_第7张图片

函数携带参数的话,模块语法没有办法提供参数给函数,就直接不执行了.

4.Django 模板语法_第8张图片

# 4.index 模板语法测试d
def index(request):
    class Myclass1(object):
        def get_self(self):
            print(0)
            return self

        @staticmethod  # 静态方法,不传递self参数, 函数中不需要self
        def func():
            print(1)
            return '静态方法'

        @classmethod  # 类使用属性方法,将自己做第一个参数进行传递
        def get_class(cls):
            print(2)
            return cls

    print(locals())
    return render(request, 'index.html', locals())

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模板语法测试title>
head>
<body>
    <h1>模板语法测试h1>
    
    <p> {{ Myclass1.get_self }} p>
    <p> {{ Myclass1.func }} p>
    <p> {{ Myclass1.get_class }} p>
body>
html>

4.Django 模板语法_第9张图片

只有是函数名称空间中名称都会被 locals()查出来,传到前端页面中.

4.Django 模板语法_第10张图片

3. 过滤器

过滤器是模板语法的内置方法。
Django内置有60多个过滤器。

过滤器的基本语法:
{{ 数据|过滤器:参数}}
自定义的过滤器的参数最多就2

3.1 常见过滤器

1. length         统计长度 (内部源码len())
2. default        默认值 第一个数据布尔值为True就展示第一个数据的值,否则就展示冒号后面的值。
3. filesizeformat 文件大小,将字节进行对应的单位换算。
4. date           日期格式。
5. slice          切片操作, 支持步长。
6. truncatechars  切取字符,三个点就占三个字符,设置大于3,不然就看到三个点。
7. truncatewords  按空格切取单词,不不包含三个点。
8. cut            移除特定的字符
9. join           拼接操作
10. add           加法
11. safe          转义
1. 统计长度
length  统计长度 (内部源码len())
	str_ = '1234'

    <p>长度统计: {{ str_|length }} </p>   

    # 统计长度:3

4.Django 模板语法_第11张图片

2.默认值
default 默认值 |前面的数据 布尔值为True 就展示第一个数据的值,否则就展示default冒号后面的值。
    bool_0 = True
    bool_1 = False

    <p> {{ bool_0|default:'前面的值为True 我就不打印' }} </p>
    <p> {{ bool_1|default:'前面的值为False 我不打印' }} </p>

4.Django 模板语法_第12张图片

3.文件大小
filesizeformat 文件大小,将字节进行对应的单位换算。
    file_size1 = 1000000
    file_size2 = 56565265

    <p>{{ file_size1|filesizeformat }}</p>
    <p>{{ file_size2|filesizeformat }}</p>

    # 976.6 KB
    # 53.9 MB

4.Django 模板语法_第13张图片

4.日期格式
格式设置 date:'Y-m-d H:i:s'  配合datetime使用
    import datetime
    now_time = datetime.datetime.now()
    
    <p>现在时间:{{ current_time }}</p>
    <p>格式设置:{{ current_time|date:'Y-m-d H:i:s' }}</p>

    # 现在时间:Aug. 15, 2021, 8:08 p.m.
    # 格式设置:2021-08-15 20:08:23

4.Django 模板语法_第14张图片

5.切片操作
slice切片操作, 支持步长。
    list_ = ['qz', 'qq', 'cc', 'dd']

    <p>切片操作:{{ list_|slice:'0:3:2' }}</p>

    # 切片操作:['qz', 'cc']

4.Django 模板语法_第15张图片

6.切取字符
truncatechars 切取字符,默认有三个点占三个字符,设置大于3,不然就看到三个点。
    info = "abcdefghijklmnopqrst"

    <p>窃取操作:{{ info|truncatechars:3 }}</p>
    <p>窃取操作:{{ info|truncatechars:6 }}</p>

    # 切取操作:...
    # 切取操作:abc...

4.Django 模板语法_第16张图片

7.切取单词
truncatewords:x 按空格取分单词,切x个.   末尾有三个点。
    msg = 'hao hao xue xi ha ha'

    <p>切取单词:{{ egl|truncatewords:3 }}</p>

    # 切取单词:hao hao xue ...

4.Django 模板语法_第17张图片

8.移除特定的字符
cut 移除特定的字符
    msg = 'hao hao xue xi ha ha'

    <p>移除特定字符:{{ egl|cut:' ' }}</p>
    <p>移除特定字符:{{ egl|cut:'cao' }}</p>

    # 移除特定字符:nihaoawocaolei
    # 移除特定字符:ni hao a wo lei

4.Django 模板语法_第18张图片

9.拼接操作
join 拼接操作 每个元素添加字符
(* 只能是字符串做拼接)
    msg = 'hao hao xue xi ha ha'
    list_ = ['qz', 'qq', 'cc', 'dd']


    <p>拼接操作:{{ msg|join:'---' }}</p>
    <p>拼接操作:{{ list_|join:'---' }}</p>

    # 拼接操作:h---a---o--- ---h---a---o--- ---x---u---e--- ---x---i--- ---h---a--- ---h---a
    # 拼接操作:qz---qq---cc---dd

4.Django 模板语法_第19张图片

10.加法
add 数字相加, 字符串拼接,否则 ' '空字符串。
    str1 = '100'
    str2 = 'aaa'

    <p>加法运算:{{ str1|add:100 }}</p>
    <p>加法拼接:{{ str2|add:s3}}</p>

# 加法运算:200
# 加法拼接:aaa100

4.Django 模板语法_第20张图片

11.前端转义
让前端执行转义。
    h1 = '

xxx

'
<p>前端转义:{{ h1|safe }}</p> # 前端转义:xxx (1号标题)

4.Django 模板语法_第21张图片

后端转义:
以后在写全栈项目的时候,前端页面不一定要在前端页面书写,
也可以在后端写好,然后传递给前端页面,需要使用 mark_safe模块.

from django.utils.safestring import  mark_safe('html代码')
res = mark_safe('html代码')
    from django.utils.safestring import mark_safe
    res = mark_safe('

xxx

'
) <p>转义:{{ res }}</p> # 后端转义:xxx (1号标题)

4.Django 模板语法_第22张图片

4. 标签

{% 开始 %} 

{% 结束 %}

4.1 for循环

{% for 变量 in  %} 
	{{循环体}}
{% endfor %}
list_  = ['aa', 'bb', 'cc', 'dd', 'dd']
	
    {% for i in list_  %}   
        
        <p> {{ i }} p>         
    {% endfor %}

4.Django 模板语法_第23张图片

4.2 forloop 参数

forloop 一个排序信息的字典
forloop.字典中的键取到值.
    # forloop 参数
    {% for foo in list_  %}
        <p> {{ forloop }} p>

    {% endfor %}

4.Django 模板语法_第24张图片

    {% for foo in list_ %}
        <p>
            {{ forloop.counter0 }} {{ forloop.counter }}
            {{ forloop.revcounter0 }} {{ forloop.revcounter }}
            {{ forloop.first }} {{ forloop.last }}
        p>

    {% endfor %}

4.Django 模板语法_第25张图片

4.3 if判断

{% if判断语句 %}
	if表达式为真执行的代码块
{% elif num == 10 %}
	if表达式为真执行的代码块
{% else %}
	所有条件都不满足执行的代码块
{% endif %}
num  = 18
{% if num >= 18 %}
	<p>成年了p>
{% elif num < 18 %}
	<p>未成年p>
{% else %}
	<p>年龄写错了p>
{% endif %}

4.Django 模板语法_第26张图片

4.4 for 与 if 混用

{% for 变量 in  %}
	{% iif判断语句 %}
        if表达式为真执行的代码块
    {% elif forloop.last %}
	   if表达式为真执行的代码块
	{% endif %}
{% endfor %}
list_ = ['aa', 'bb', 'cc', 'dd', 'dd']
    <!--下面写测试的模板语法-->
    {% for i in list_ %}
        {% if forloop.first %}
            <p> 第一个值: {{ i}} </p>
        {% elif forloop.last %}
           <p> 最后一个值: {{ i }} </p>
        {% endif %}
    {% endfor %}

4.Django 模板语法_第27张图片

4.5 empty

for循环的可迭代对象为空时执行。
list_ = [1, 2]
{% for i in list_  %}
	<p> {{ i }} p>
{% endfor %}
<empty>
    <p>3p>
empty>

4.Django 模板语法_第28张图片

4.6 for遍历字典

for 变量字典 默认只能拿到键
模板语法中可
字典可以使用.keys   获取所有的键
字典可以使用.values 获取所有的值
字典可以使用.items  获取键值对
.
    dict_ = {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
    {% for i in dict_.keys  %}
        <p> {{ i }} p>
    {% endfor %}

    {% for i in dict_.values  %}
        <p> {{ i }} p>
    {% endfor %}

    {% for i in dict_.items  %}
        <p> {{ i }} p>
    {% endfor %}

4.Django 模板语法_第29张图片

4.7 with起别名

在with语法内可以通过as起别名,一个别名代替一个模板语法取值语句。
别名快速的到前面复杂的模板语法中取值。

{% with 取值表达式 as 别名 %}
	{{别名}}
{% withend %}
    dict_ = {'name': ['you', {'小名': ['二狗子', '狗剩']}]}

    <p>{{ dict_.name.1.小名.1}}</p>
    {% with dict_.name.1.小名.1 as yourname %}
    <p>{{ yourname }}p>
    <p>{{ yourname }}p>
    {% endwith %}

4.Django 模板语法_第30张图片

5. 自定义模板语法

过滤器、标签、inclusion_tag
必须步骤:
1.在app应用下创建一个名字叫templatetags文件夹。
2.在该文件夹内创建一个任意名称的.py文件
3.在该py文件内必须写下两个语句
	from django import template
	register = template.Library()
4. 前端先使用{% load 自动模板语法文件的名字 %}
5. {{ |name指定名字 }}  使用
0. 在app01 下创建templatetags文件夹
1. 在templatetags文件夹创建mytag.py
2. mytag.py文件内容:
    from django import template
    register = template.Library()

5.1 过滤器

* 自定义的过滤器函数最多只能有两个参数
# app01的templatetags 目录下的 my_delimit.py
from django import template

register = template.Library()


# register.过滤器(name='过滤器的名字')
@register.filter(name='my_filter')
def my_filter(num):
    # 编辑逻辑
    if num >= 18:
        msg = '成年人'
    elif num < 18:
        msg = '未成年'
    else:
        raise '请提供数据类型的数据!'
    return msg

# app01 下的 views.py 
# 4.index 模板语法测试
def index(request):
    num = 1
    return render(request, 'index.html', locals())
        
    {% load my_delimit %}
	    
    <p> {{ num|my_filter }}p>

4.Django 模板语法_第31张图片

自定义过滤器的函数只能有两个参数.
@register.filter(name='my_sum')
def my_sum(num1, num2):
    return num1 + num2
    <p> {{ num|my_sum:2 }}p>

4.Django 模板语法_第32张图片

5.2 标签

可以接受任意个参数,参数之间用空格分隔开。
类似于自定义函数。
@register.simple_tag(name='my_sum2')
def my_sum2(num1, num2, num3, num4):
    return num1+num2+num3+num4
    {% load my_delimit %}
    <p> {%  my_sum2 num1 2 3 4 %}p>

4.Django 模板语法_第33张图片

5.3 inclusion_tag

先定义一个方法,方法中指定一个模板页面.
在页面上调用该方法(可以传值)生成一些数据然后传递给模板页面.
之后将模板页面中渲染好的结果放到调用的位置

@register.inclusion_tag('模板页面.html')
@register.inclusion_tag('模板页面.html')
def  my_item(n):  # n 是多少就建多少个 第x项
    data = ['第{}项'.format(i) for i in range(n)]
    将函数的名称空间传递给 前端页面
    # print(data)
    return locals()  # 将函数的名称返回前端
['第{}项'.format(i) for i in range(n)]
列表生成器
['第1项', '第2项', ...]


<ul>
    {% for i in data %}
        <li>{{ i }}li>
    {% endfor %}
ul>


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模板语法测试title>
head>
<body>
    <h1>模板语法测试h1>
    
    
    {% load my_delimit %}
    
    {%  my_item 5 %}
body>
html>

4.Django 模板语法_第34张图片

当html页面某一个地方需要参数才能够动态的渲染出来,
并在在多个页面上都需要使用到该局部,那么将该局部页面作为inclusion_tag形式。

6. 继承模板

很多的网站页面整体都大差不差,只是某一些局部在做变化.
那么相同的地方就可以使用同提个模板,不同的地方在稍稍修改.
模板页面 models.html
{% block 区域的名字 %}         
	被替换的区域
{% endblock %}

子页面 xxx.html
{% extends 'models.html' %}  继承模板页面
{% block 区域的名字 %}        引用
 	写新的代码替换
{% endblock %}
一般情况下会留有三块可以被修改的区域。
1. css区域
2. html区域
3. js 区域
模板页面上划定的区域多,拓展性就高.(如果太多也没必要)
每一个子页面都可以有自己独立的css代码html代码js代码。

{% block css %}         
	被替换的区域
{% endblock %}

{% block html %}         
	被替换的区域
{% endblock %}

{% block js %}         
	被替换的区域
{% endblock %}

7. 继承模板案例

7.1 路由层

项目下的urls.py 写路由和视图函数的对应关系.
from django.conf.urls import url
from django.contrib import admin
# 0. 导入 数图函数
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    # 1. 注册页面
    url(r'^register/', views.register),
    # 2. 登入页面
    url(r'^login/', views.login),
    # 3. 主页
    url(r'^home/', views.home)
]

7.2 视图层

app01 应用下views.py 写视图函数.
# 0. 导入Python 三板斧
from django.shortcuts import render, HttpResponse, redirect


# 1. 主页
def home(request):
    return render(request, 'home.html')


# 2. 注册
def register(request):
    return render(request, 'register.html')


# 3. 登入
def login(request):
    return render(request, 'login.html')

7.3 模板页面

home主页,也是模板页面
设置不继承的区域.

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>主页title>
    
    {% load static %}
    
    <script src="{% static 'js/jquery-3.6.0.min.js' %}">script>
    
    <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
    
    <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}">script>
    {% block css %}
    {% endblock %}
head>
<body>

<div>
    
    <div>
        <nav class="navbar navbar-inverse">
      <div class="container-fluid">
        
        <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 navigationspan>
            <span class="icon-bar">span>
            <span class="icon-bar">span>
            <span class="icon-bar">span>
          button>
          <a class="navbar-brand" href="#">全栈开发a>
        div>

        
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
          <ul class="nav navbar-nav">
            <li class="active"><a href="#">首页<span class="sr-only">(current)span>a>li>
            <li><a href="#">我的笔记a>li>
            <li class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">学习链接<span class="caret">span>a>
              <ul class="dropdown-menu">
                <li><a href="#">Pythona>li>
                <li><a href="#">前端a>li>
                <li><a href="#">MySQLa>li>
                <li role="separator" class="divider">li>
                <li><a href="#">博客园a>li>
                <li role="separator" class="divider">li>
                <li><a href="#">CSNDa>li>
              ul>
            li>
          ul>
          <form class="navbar-form navbar-left">
            <div class="form-group">
              <input type="text" class="form-control" placeholder="在这看查询">
            div>
            <button type="submit" class="btn btn-default">搜索button>
          form>
          <ul class="nav navbar-nav navbar-right">
            <li><a href="#">收藏本页a>li>
            <li class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">状态选择<span class="caret">span>a>
              <ul class="dropdown-menu">
                <li><a href="#">a>li>
                <li><a href="#">隐身a>li>
                <li><a href="#">免打扰a>li>
                <li role="separator" class="divider">li>
                <li><a href="#">退出a>li>
              ul>
            li>
          ul>
        div>
      div>
    nav>
    div>
    
    <div class="container-fluid">
        <div class="row">
            
          <div class="col-md-4">
              
              <ul class="list-group">
                  <li class="list-group-item list-group-item-danger"><a href="/home/">主页a>li>
                  <li class="list-group-item list-group-item-success"><a href="/register/">注册a>li>
                  <li class="list-group-item list-group-item-info"><a href="/login/">登入a>li>

              ul>
          div>
            
          <div class="col-md-8">
              
              <div class="panel panel-primary">
                  
                  <div class="panel-heading">
                      <h3 class="panel-title">请看这里h3>
                  div>
                  <div class="panel-body">
                      
                      {% block content %}
                      
                      <div class="jumbotron">
                          <h1>学习入口h1>
                          <p>欢迎你的登入!p>
                          <p><a class="btn btn-primary btn-lg" href="#" role="button">进入a>p>
                      div>
                      {% endblock %}
                  div>
              div>
          div>
        div>
    div>
div>

<script>

    {% block js %}
        // js代码
        alert('主页面')
    {% endblock %}

script>

body>
html>

7.4 继承模板

0. register.html   中继承home.html页面.  
1. login.html      中继承home.html页面.

{% extends 'home.html' %}


{% block css %}

{% endblock  %}


{% block content %}

{% endblock  %}



{% block js %}

{% endblock  %}

4.Django 模板语法_第35张图片

2. 在浏览器中 127.0.0.1:8000/home  
3. 在浏览器中 127.0.0.1:8000/register  
4. 在浏览器中 127.0.0.1:8000/login

4.Django 模板语法_第36张图片

* 修改模板的栅格 1 - 11 所有是有这个模板的页面都会跟着改变.

4.Django 模板语法_第37张图片

7.5 注册页面


{% extends 'home.html' %}


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


{% block content %}
    <div>
        <form action="" method="post">
            <h1 class="text-center">注册页面h1>
            <p>用户名称:
                <input type="text" name="username" class="form-control">
            p>
            <p>用户密码:
                <input type="password" name="password" class="form-control">
            p>
            <input type="submit" value="注册" class="btn btn-block btn-info">
        form>
    div>
{% endblock  %}



{% block js %}
    alert('注册页面')
{% endblock  %}

7.6 登入界面


{% extends 'home.html' %}


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


{% block content %}
    <div>
        <form action="" method="post">
            <h1 class="text-center">登入页面h1>
            <p>用户名称:
                <input type="text" name="username" class="form-control">
            p>
            <p>用户密码:
                <input type="password" name="password" class="form-control">
            p>
            <input type="submit" value="登入" class="btn btn-block btn-info">
        form>
    div>
{% endblock  %}



{% block js %}
    alert('登入页面')
{% endblock  %}
0. 在浏览器中 127.0.0.1:8000/home  
1. 在浏览器中 127.0.0.1:8000/register  
2. 在浏览器中 127.0.0.1:8000/login

4.Django 模板语法_第38张图片

8. 导入模板

将页面当作是一个模块,需要的时候直接导入。
0. 项目下 路由层 urls.py 添加代码
1. app01 应用下 视图层 views.py 添加代码
2. 项目下 templates 目录  models.html 写模板
3. 项目下 templates 目录  index.html 引用模板
    # 4. 索引
    url(r'^index', views.index)
# 4. 目录索引
def index(request):
    return render(request, 'index.html')


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>主页title>
    
    {% load static %}
    
    <script src="{% static 'js/jquery-3.6.0.min.js' %}">script>
    
    <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
    
    <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}">script>
    {% block css %}
    {% endblock %}
head>
<body>

<div class="jumbotron">
  <h1>Hello, world!h1>
  <p>...p>
  <p><a class="btn btn-primary btn-lg" href="#" role="button">Learn morea>p>
div>

body>
html>


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>测试页面title>
head>
<body>

{% include 'models.html' %}
body>
html>

4.Django 模板语法_第39张图片

你可能感兴趣的:(3.Django,safari,chrome,javascript)