一、django的设计模式和模板层
1.传统的MVC
M模型层(Model,主要用于对数据库层封装)
V视图层(View,用于向用户展示结果(什么数据(找数据)+怎么显示what+how))
C控制层(Controller,整个系统核心,用于处理请求、获取 数据、返回结果)
2.MTV
M模型层(Model,负责与数据库交互)
T模板层(Template,负责呈现内容到浏览器(how),就是根据视图中传递的字典信息动态⽣产html页面)
V视图层(View,是核心,负责接收请求、获取数据、返回结果(什么数据(找数据)what))
相当于把MVC中的V拆开成了T和V,功能分化地更加精准了。另外MVT也有C,就是主路由,但是只负责url的分发,所以⽐较简单,之前讲过了。
2.1 模板层(Template):是可以根据字典数据动态变化的html网页。模板可以根据视图(视图层找数据,比如视图获取form表单的数据)传递的字典数据动态生成HTML网页。
·模板配置:
1.创建模版⽂件夹:在项目文件夹下创建templates文件夹
2.settings.py中TEMPLATES配置项
BACKEND:指定模版的引擎(用自带的即可,这个可以不要管)
DIRS:模版的搜索⽬录(⼀个或者多个)
APP_DIRS:是否要在应⽤中的templates⽂件夹中搜索模版⽂件
OPTIONS:有关模版的选项
3、配置项中需要修改的部分
设置DIRS - 'DIRS':[BASE_DIR/'templates']
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR/'templates'],#就改这里即可
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
另外语言和地点也可以改一下:
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'
·加载模板
方案一:通过loader获取模板,通过HttpResponse进行响应
#视图函数中
from django.template import loader
#1.通过loader加载模板
t = loader.get_template('模板文件名')
#2.将t转换成HTML字符串
html = t.render(字典数据)
#3.用相应对象将转换的字符内容返回给浏览器
return HttpResponse(html)
#方案一相对比较麻烦
方案二:使用render()直接加载病响应模板(注意不是刚才那个render)
#在视图函数中
from django.shortcuts import render
return render(request,'模板文件名',字典数据)
·视图层与模板层之间的交互
视图必须是可以向模板层html传数据的,因为视图负责找数据,模板负责显示数据。
1.视图函数可以将python变量封装字典中传递到模板。(必须是字典)
def xxx_view(request):
dic = {
"变量1":"值1",
"变量2":"值2",
}
return render(request,'xxx.html',dic)
2.模板中,我们可以用{{变量名}}的语法调用视图传进来的变量
例如:
<body>
<h3>{{username}}是模板层的</h3>
</body>
能传递到模板中的数据类型:
str字符串 int整型 list数组 tuple元组 dict字典 func方法 obj类实例化对象
变量如果是容器,比如list,可以{{变量名.index}}作为索引形式
变量如果是字典,可以{{变量名.key}}去获取值
变量如果是实例化对象,可以{{对象.方法}}获取方法#不需要加括号
·模板标签
作用:将一些服务端的功能嵌入到模板中,例如流程控制
if语句
{% if xxx %}
{% elif xxx %}
{% else xxx %}
{% endif %}
例如:
{% if op == 'add' %} selected {% endif %}
或
{% if x>10 %}
x>10
{% else %}
x!>10
{% endif %}
注意:这里==前后都必须有空格(虽然pycharm会标红)
for语句
{% for 变量 in 可迭代对象 %}
...循环语句
{% empty %}
...可迭代对象⽆数据时的填充语句
{% endfor %}
for训练⾥⾯的内置变量--forloop
forloop.counter 循环的当前迭代(从1开始)
forloop.counter0 循环的当前迭代(从0开始)
forloop.recounter 上述的反向
forloop.recounter0 上述的反向
forloop.first 如果是第⼀次迭代则为真
forloop.last 如果是最后⼀次迭代则为真
forloop.parentloop 当潜逃循环,表示外层循环
·模板层的过滤器
定义:在变量输出时对变量的值进行处理。可以通过使用过滤器来变换变量的输出显示,这个修改的过程就不必在视图里做了。
语法:
注意这里也是双大括号
{{变量|过滤器1:'参数1'|过滤器2:'参数2'|...}}
常用的过滤器:
lower、 upper --大小写
safe --自动开启的,默认不对变量内的字符进行html转义(例如输⼊的字符串可能是html代码,加上这个后就不会执行,而是单纯的⼀段字符串),加上safe就会执行html代码。
add:'n' --将值都加n
truncatechars:'n' --对长度大于n的进⾏截断,⽤...代替
举例: <h3>str is {{str|upper}}</h3>
·模板层的继承
很多网站的各个页面的基本框架样式一样,如果挨个写html的话显然麻烦,万一需要改动,也需要挨个修改,太累赘。这就用到了模板的继承。模板继承可以使父模板的内容重用,子模板直接继承父模板的全部内容,也可以覆盖父模板中相应的块。
语法:
父模板中:
·定义父模板中的块block标签
·标识出在哪些子模块中是允许被修改的
·block标签:在父模板中定义,可以在子模板中覆盖
子模板中:
·继承模板extends标签(卸载模板文件的第一行)
例如:{% extends 'base.html' %}
·子模板重写父模板中的内容块:
{% block block_name %}
子模板块用来覆盖父模板中block_name块的内容
{% endblock block_name %}
3.URL反向解析
代码中url出现的情况:
1.html模板中:
·<a href = 'url'>超链接</a>
·<form action = 'url' method = 'post'> form表单中的数据,用post方法提交至url
2.视图函数中 302跳转
HttpResponseRedirect('url') 将用户地址栏中的地址跳转到该url
URL的书写规范
1.绝对地址: http://127.0.0.1:8000/page/1(其次可以选,但是比较麻烦)
2.相对地址:
/page/1 (该方法会自动加上协议、 ip、端口+相对地址=最终访问地址)(首选该方法)
page/1 (当前地址栏的最后⼀个/前内容+相对地址=最终访问地址)(最好别用)
URL反向解析
是指在视图或者模板中,用path定义的名称(别名)来动态查询或计算出相应的路由。
path函数的语法:
path(route,views,name="别名")
path('page',views.page_view,name='page_url')
根据path中的‘name=’关键字传参给url确定了一个唯一确定的名字,在模板或视图中,可以通过这个名字反向推断出此url信息。
模板中,通过url标签实现地址反向解析
{% url '别名' %}
{% url '别名' '参数1' '参数2' %}
例如:
{% url 'pagen' '400' %}
{% url 'person' age='18' name='rhj' %}
后面带的参数是路由中存在转换器的情况
我比较喜欢别名的方法,url实时动态更新,不需要手动修改,永远不会错。
在视图函数中,可以调用django中的reverse返回发进行反向解析:
语法:
from django.urls import reverse
reverse('别名',args=[],kwargs={})
例⼦:
def test(request,age):
#302跳转
from django.urls import reverse
url=reverse('base_index',args=[],kwargs={})
return HttpResponseRedirect(url)
4.静态文件
静态文件即图片,视频,音频,css
4.1静态文件配置
1.需要配置静态文件的访问路径(该配置默认存在)
·通过哪个url地址找到静态文件
·STATIC_URL = '/static/'代表静态请求,直接加载静态文件,不需要视图函数
2.还需要配置静态文件的存储路径STATICFILES_DIRS
存储路径,告诉框架静态⽂件在哪,在服务器的什么位置
STATICFILES_DIRS=(
os.path.join(BASE_DIR,'static'),
)
静态文件访问方法:
⽅法1:
html中:用相对地址和绝对地址
<img src='/static/image/dog.jpg' width='200px' height='200px'>
<img src="http://127.0.0.1:8000/static/image/doog.png" width="200px" height='200px'>
⽅法2:
1.先加载(加载⼀次即可){% load static %}
2.{% static '静态资源'%}
<img src='{% static 'images/a.jpg' %}'>
如果想要加载的路径,例如改成: statics,那么只需要改 STATIC_URL='/statics/' 即可(但是该⽅法只适合⽅法2,建议⽤⽅法2去配置静态资源
例子:
<img scr="{%static 'images/dog.jpg' %}">
注意这里路径不要带static,