阅读:49
FBV(基于函数的视图)
CBV(基于类的视图)
Python 是一个门面向对象的编程语言。如果我们只用函数来编写视图函数,
那么就会造成很多面向对象的优点无法利用起来,比如说封装、继承、多态等
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页面')
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 请求')
<!--项目目录下建立login.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登入页面</title>
</head>
<body>
<div>
<form action="" method="post">
<input type="submit">
</form>
</div>
</body>
</html>
3. 在浏览器中输入: 127.0.0.1:8000/login
4. 点提交
函数名,方法名加括号执行优先级最高。
在启动 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
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)
"""
其他的不看了
"""
模板语法的书写方法:
{{ 变量名 }} 变量相关
{% %} 逻辑相关 for循环等
基本的数据类型都可以传递给前端。
模板语法内部会自动判断当前的变量(函数名, 类名)是否可以加括号调用,
如果可以就会自定加括号执行。
传递函数名会自动加括号进行调用,传递的是返回值.
传递类名的时候也会自动加括号实例化,传递的是对象.
* 模板语法不支持函数传递额外的参数,如果函数带参数则不会执行这条模板语法语句。
Django模板语法的取值格式:
1. 句点符 .键取值
2. 可以点索引
3. 两者混合使用
# 项目的urls.py
# 4.索引
url('^index/', views.index)
# app01的views.py
# 4.index 模板语法测试
def index(request):
# 返回index.html 页面
return render(request, 'index.html')
templates目录下创建index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板语法测试</title>
</head>
<body>
<h1>模板语法测试</h1>
<!--下面写测试的模板语法-->
</body>
</html>
模板语法可以传入后端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())
<!-- templates 在 index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板语法测试</title>
</head>
<body>
<h1>模板语法测试</h1>
<!--下面写测试的模板语法-->
{{ int_ }}
{{ float_ }}
{{ str_ }}
{{ list_ }}
{{ tuple_ }}
{{ dict_ }}
{{ set_ }}
{{ bool_ }}
</body>
</html>
.键取值
索引取值
值可以使用方法.
# 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())
<!-- templates 在 index.html -->
<!DOCTYPE html>
<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>
# app01 views.py
# 4.index 模板语法测试
def index(request):
def func1():
return 'func1 的返回值'
# 返回index.html 页面
print(locals())
return render(request, 'index.html', locals())
<!-- templates 在 index.html 中-->
<p> {{ func1 }} </p>
函数携带参数的话,模块语法没有办法提供参数给函数,就直接不执行了.
# 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())
<!DOCTYPE html>
<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>
只有是函数名称空间中名称都会被 locals()查出来,传到前端页面中.
过滤器是模板语法的内置方法。
Django内置有60多个过滤器。
过滤器的基本语法:
{{ 数据|过滤器:参数}}
自定义的过滤器的参数最多就2个
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 转义
length 统计长度 (内部源码len())。
str_ = '1234'
<p>长度统计: {{ str_|length }} </p>
# 统计长度:3
default 默认值 |前面的数据 布尔值为True 就展示第一个数据的值,否则就展示default冒号后面的值。
bool_0 = True
bool_1 = False
<p> {{ bool_0|default:'前面的值为True 我就不打印' }} </p>
<p> {{ bool_1|default:'前面的值为False 我不打印' }} </p>
filesizeformat 文件大小,将字节进行对应的单位换算。
file_size1 = 1000000
file_size2 = 56565265
<p>{{ file_size1|filesizeformat }}</p>
<p>{{ file_size2|filesizeformat }}</p>
# 976.6 KB
# 53.9 MB
格式设置 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
slice切片操作, 支持步长。
list_ = ['qz', 'qq', 'cc', 'dd']
<p>切片操作:{{ list_|slice:'0:3:2' }}</p>
# 切片操作:['qz', 'cc']
truncatechars 切取字符,默认有三个点占三个字符,设置大于3,不然就看到三个点。
info = "abcdefghijklmnopqrst"
<p>窃取操作:{{ info|truncatechars:3 }}</p>
<p>窃取操作:{{ info|truncatechars:6 }}</p>
# 切取操作:...
# 切取操作:abc...
truncatewords:x 按空格取分单词,切x个. 末尾有三个点。
msg = 'hao hao xue xi ha ha'
<p>切取单词:{{ egl|truncatewords:3 }}</p>
# 切取单词:hao hao xue ...
cut 移除特定的字符
msg = 'hao hao xue xi ha ha'
<p>移除特定字符:{{ egl|cut:' ' }}</p>
<p>移除特定字符:{{ egl|cut:'cao' }}</p>
# 移除特定字符:nihaoawocaolei
# 移除特定字符:ni hao a wo lei
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
add 数字相加, 字符串拼接,否则 ' '空字符串。
str1 = '100'
str2 = 'aaa'
<p>加法运算:{{ str1|add:100 }}</p>
<p>加法拼接:{{ str2|add:s3}}</p>
# 加法运算:200
# 加法拼接:aaa100
让前端执行转义。
h1 = '<h1>xxx</h1>'
<p>前端转义:{{ h1|safe }}</p>
# 前端转义:xxx (1号标题)
后端转义:
以后在写全栈项目的时候,前端页面不一定要在前端页面书写,
也可以在后端写好,然后传递给前端页面,需要使用 mark_safe模块.
from django.utils.safestring import mark_safe('html代码')
res = mark_safe('html代码')
from django.utils.safestring import mark_safe
res = mark_safe('<h1>xxx</h1>')
<p>转义:{{ res }}</p>
# 后端转义:xxx (1号标题)
{% 开始 %}
{% 结束 %}
{% for 变量 in 值 %}
{{循环体}}
{% endfor %}
list_ = ['aa', 'bb', 'cc', 'dd', 'dd']
<!--for i in lll-->
{% for i in list_ %}
<!--一个个元素-->
<p> {{ i }} </p>
{% endfor %}
forloop 一个排序信息的字典
forloop.字典中的键取到值.
# forloop 参数
{% for foo in list_ %}
<p> {{ forloop }} </p>
{% endfor %}
{% for foo in list_ %}
<p>
{{ forloop.counter0 }} {{ forloop.counter }}
{{ forloop.revcounter0 }} {{ forloop.revcounter }}
{{ forloop.first }} {{ forloop.last }}
</p>
{% endfor %}
{% if判断语句 %}
if表达式为真执行的代码块
{% elif num == 10 %}
if表达式为真执行的代码块
{% else %}
所有条件都不满足执行的代码块
{% endif %}
num = 18
{% if num >= 18 %}
<p>成年了</p>
{% elif num < 18 %}
<p>未成年</p>
{% else %}
<p>年龄写错了</p>
{% endif %}
{% 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 %}
for循环的可迭代对象为空时执行。
list_ = [1, 2]
{% for i in list_ %}
<p> {{ i }} </p>
{% endfor %}
<empty>
<p>3</p>
</empty>
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 %}
在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 %}
过滤器、标签、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()
* 自定义的过滤器函数最多只能有两个参数
# 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())
<!--0.必须先导入文件-->
{% load my_delimit %}
<!--1.使用-->
<p> {{ num|my_filter }}</p>
自定义过滤器的函数只能有两个参数.
@register.filter(name='my_sum')
def my_sum(num1, num2):
return num1 + num2
<p> {{ num|my_sum:2 }}</p>
可以接受任意个参数,参数之间用空格分隔开。
类似于自定义函数。
@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>
先定义一个方法,方法中指定一个模板页面.
在页面上调用该方法(可以传值)生成一些数据然后传递给模板页面.
之后将模板页面中渲染好的结果放到调用的位置
@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项', ...]
<!-- 项目的 templates 文件 新建一个html文件 文件中只有以下内容,没有其他的东西-->
<!--模板页面-->
<ul>
{% for i in data %}
<li>{{ i }}</li>
{% endfor %}
</ul>
<!-- 项目的 templates 文件 下的 index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板语法测试</title>
</head>
<body>
<h1>模板语法测试</h1>
<!--下面写测试的模板语法-->
<!--0.先导入创建的自动模板语法的文件-->
{% load my_delimit %}
<!--调用-->
{% my_item 5 %}
</body>
</html>
当html页面某一个地方需要参数才能够动态的渲染出来,
并在在多个页面上都需要使用到该局部,那么将该局部页面作为inclusion_tag形式。
很多的网站页面整体都大差不差,只是某一些局部在做变化.
那么相同的地方就可以使用同提个模板,不同的地方在稍稍修改.
模板页面 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 %}
项目下的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)
]
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')
home主页,也是模板页面
设置不继承的区域.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页</title>
<!--0. 动态获取令牌-->
{% load static %}
<!--1. 导入 jQuery-->
<script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>
<!--2. 导入 bootstrap css 文件-->
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<!--3. 导入 bootstrap js 文件-->
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
{% block css %}
{% endblock %}
</head>
<body>
<!--4.页面布局-->
<div>
<!--5. 导航条-->
<div>
<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="#">全栈开发</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="#">首页<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="#">Python</a></li>
<li><a href="#">前端</a></li>
<li><a href="#">MySQL</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">博客园</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">CSND</a></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><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
</div>
<!--6. 栅格系统 4 / 8 container-fluid 占据全部视野-->
<div class="container-fluid">
<div class="row">
<!--7.左边布局-->
<div class="col-md-4">
<!--7.1列表组-->
<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>
<!--8.右边布局-->
<div class="col-md-8">
<!--8.1情境效果-->
<div class="panel panel-primary">
<!--8.2带标题的面板-->
<div class="panel-heading">
<h3 class="panel-title">请看这里</h3>
</div>
<div class="panel-body">
<!--9.替换的内容-->
{% block content %}
<!--8.3巨幕-->
<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>
0. register.html 中继承home.html页面.
1. login.html 中继承home.html页面.
<!--0.引用模板-->
{% extends 'home.html' %}
<!--css 局部修改-->
{% block css %}
{% endblock %}
<!--html 局部修改-->
{% block content %}
{% endblock %}
<!--js 局部修改-->
{% block js %}
{% endblock %}
2. 在浏览器中 127.0.0.1:8000/home
3. 在浏览器中 127.0.0.1:8000/register
4. 在浏览器中 127.0.0.1:8000/login
* 修改模板的栅格 1 - 11 所有是有这个模板的页面都会跟着改变.
<!--0.引用模板-->
{% extends 'home.html' %}
<!--css 局部修改-->
{% block css %}
<style>
h1 {
color: gold;
}
</style>
{% endblock %}
<!--html 局部修改-->
{% 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 %}
<!--js 局部修改-->
{% block js %}
alert('注册页面')
{% endblock %}
<!--0.引用模板-->
{% extends 'home.html' %}
<!--css 局部修改-->
{% block css %}
<style>
h1 {
color:chartreuse;
}
</style>
{% endblock %}
<!--html 局部修改-->
{% 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 %}
<!--js 局部修改-->
{% 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
将页面当作是一个模块,需要的时候直接导入。
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')
<!--models.html 模板-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页</title>
<!--0. 动态获取令牌-->
{% load static %}
<!--1. 导入 jQuery-->
<script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>
<!--2. 导入 bootstrap css 文件-->
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<!--3. 导入 bootstrap js 文件-->
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
{% block css %}
{% endblock %}
</head>
<body>
<!--4. 巨幕-->
<div class="jumbotron">
<h1>Hello, world!</h1>
<p>...</p>
<p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
</div>
</body>
</html>
<!--index.html 模板-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试页面</title>
</head>
<body>
<!--导入模板-->
{% include 'models.html' %}
</body>
</html>