Django后端框架(三)

【MVC和MTV】

  • MVC(Model模型-View视图-Controller控制器):降低模块间的耦合度(解耦)
    • M:模型层,主要用于对数据库层的封装
    • V:视图层,用于向用户展示结果(WHAT+HOW)
    • C:控制器,用于处理请求、获取数据、返回结果(重要!)

  • MTV(Model模型-Template模板-View视图):降低模块间的耦合度(解耦)
    • M:模型层,负责与数据库交互(重点!)
    • T:模板层,负责呈现内容到浏览器(HOW)
    • V:视图层,核心,负责接收请求、获取数据、返回结果(WHAT)

*MTV模式中C(控制器)仍然存在,在Django中是主路由。

【模板层】

模板:是可以根据字典数据动态变化的html网页。

模板可以根据视图中传递的字典数据动态生成相应的HTML 网页。

  • 模板配置:
    1. 直接在项目文件夹下创建模板文件夹:<项目名>/templates
    2. 在settings.py中TEMPLATES配置项:
      1. BACKEND:指定模板的引擎(怎么去接收视图传递的数据、怎么调用)
      2. DIRS:模板的搜索目录(可以是一个或多个)
      3. APP_DIRS:是否要在应用中的templates文件夹中搜索模板文件
      4. OPTIONS:有关模板的选项

# 设置DIRS

'DIRS': [os.path.join(BASE_DIR, 'templates')]

  • 加载模板
    1. 方案一:通过loader获取模板,通过HttpResponse进行响应
    2. 方案二:使用render()直接加载并响应模板
    # 在视图函数文件中
    
    ## 方案一
    # 0.导入loader
    from django.template import loader
    # 1.通过loader加载模板
    t = loader.get_template("模板文件名")
    # 2.将t转换为html字符串
    html = t.render(字典数据)
    # 3.用响应对象将转换的字符串内容返回给浏览器
    return HttpResponse(html)
    
    ## 方案二
    from django.shortcuts import render
    return render(request, '模板文件名', 字典数据)  # 第三个参数可有可无

【视图层与模板层之间的交互】

  • 视图函数中可以将Python变量封装到字典中传递到模板
def xxx_view(request):
    dic = {
        "变量1":"值1",
        "变量2":"值2"
    }
    return render(request, 'xxx.html', dic)
  • 模板中,我们可以用{{ 变量名 }}的语法来调用视图传进来的变量

【模板的变量】

*能传递到模板中的数据类型:str、int、list、tuple、dict、func(方法)、obj(类实例化对象)

  • 在模板中使用变量语法:
    • {{ 变量名 }}
    • {{ 变量名.index }}
    • {{ 变量名.key }}
    • {{ 对象.方法 }}
    • {{ 函数名 }}

样例:

# 视图函数
def test_html_param(request):
    dic = {}
    dic['int'] = 88
    dic['str'] = 'Cindy'
    dic['lst'] = ['Tom', 'Jack', 'Lily']
    dic['dict'] = {'a':9, 'b':8}
    dic['func'] = say_hi  # 函数
    dic['class_obj'] = Dog()  # 类
    return render(request, 'test_html_param.html', dic)

def say_hi():
    return 'hahaha'

class Dog:
    return 'wangwang'

接着在html文件(模板层)中调用视图层的变量。

<body>
<h3>int是{{ int }}</h3>
<h3>str是{{ str }}</h3>
<h3>lst是{{ lst }}</h3>
<h3>lst是{{ lst.0 }}</h3>
<h3>dict是{{ dict }}</h3>
<h3>dict['a']是{{ dict.a }}</h3>
<h3>function是{{ func }}</h3>
<h3>class_obj是{{ class_obj.say }}</h3>
</body>

输出:

int是88

str是Cindy

lst是['Tom', 'Jack', 'Lily']

lst是Tom

dict是{'a':9, 'b':8}

dict['a']是9

function是hahaha

class_obj是wangwang

【模板标签】

作用:将一些服务器端的功能嵌入到模板中,例如流程控制等

语法:

{% 标签 %}

...

{% 结束标签 %}

  • if标签
    • if条件表达式里可以用的运算符有 ==, !=, <, >, <=, >=, in, not in, is, is not, not, and, or
    • 在if标记中使用实际括号是无效的语法。如果需要它们指示优先级,则应使用嵌套的if标记

{% if 条件表达式1 %}

...

{% elif 条件表达式2 %}

...

{% elif 条件表达式3 %}

...

{% else %}

...

{% endif %}

<!--样例,当前x为调用的变量-->
<body>
{% if x > 10 %}
今天天气很好
{% else %}
今天天气非常好
{% endif %}
</body>
  • for标签

{% for 变量 in 可迭代对象 %}

        ... 循环语句

{% empty %}

        ... 可迭代对象无数据时填充的语句

{% endfor %}

*内置变量:forloop

变量描述
forloop.counter循环的当前迭代(从1开始索引)
forloop.counter()循环的当前迭代(从0开始索引)
forloop.revcountercounter值的倒序
forloop.revcounter()revcounter值的倒序
forloop.first如果这是第一次通过循环,则为真
forloop.last如果这是最后一次循环,则为真
forloop.parentloop当嵌套循环,parentlop表示外层循环
<!--样例,当前name和lst为调用的变量-->
<body>
{% for name in lst %}
    {% if forloop.first %} *** {% endif %}  <!--第一行前显示n三个星号-->
    <p>
    {{ name }}</p>  <!--按顺序打印出name-->
    {% if forloop.last %} === {% endif %}  <!--最后一行后显示三个等号-->
{% empty %}
    当前无数据  <!--按若无数据则显示此行-->
{% endfor %}


<<<练习-模板标签>>>

写一个简单的计算器页面,能够在服务端进行简单加减乘除计算,开始计算后仍显示原页面,且输入的数值和选择的运算符保持不变。

视图函数:

def test_mycal(request):
    if request.method == 'GET':
        return redner(request, 'mycal.html')
    elif request.method == 'POST':
        # 处理计算
        x = request.POST['x']
        y = request.POST['y']
        op = request.POST['op']
        
        result = 0
        if op == 'add':
            result = x + y
        elif op == 'sub':
            result = x - y
        elif op == 'mul':
            result = x * y
        elif op == 'div':
            result = x / y

    return render(request, 'mycal.html', locals())  # locals()会将以上局部变量直接封装成一个字典

模板页面:

<form action='/mycal' method='post'>
    <input type='text' name="x" value="{{ x }}">
    <select name='op'>
    <option value="add"  {% if op == 'add' %}selected{% endif %}>加</option>  <!--添加了selected属性的会默认第一个显示-->
    <option value="sub"  {% if op == 'sub' %}selected{% endif %}>减</option>
    <option value="mul"  {% if op == 'mul' %}selected{% endif %}>乘</option>
    <option value="div"  {% if op == 'div' %}selected{% endif %}>除</option>
    </select>
    <input type='text' name="y" value="{{ y }}">
<span>{{ result }}</span>
    <div><input type="submit" value='开始计算'></div>
</form>

结果:

初始页面:

计算后,文本框内输入的数值依然显示,选择的运算符保持不变:


【模板过滤器】

定义:在变量输出时对变量的值进行处理

作用:可以通过使用过滤器来改变变量的输出显示

语法:

{{ 变量 | 过滤器1:'参数值1' | 过滤器2:'参数值2'... }}

常用过滤器:

过滤器说明
lower将字符串转换为全部小写
upper将字符串转换为大写形式
safe默认不对变量内的字符串进行html转义(即把该字符串以html代码的形式运行出来)
add: "n"将value的值增加n
truncatechars: 'n'如果字符串的字符多于制定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列("...")结尾

样例:

<h3>{{ int|add:'2' }}</h3>  <!--将int增加2-->
<h3>{{ str|upper }}</h3>  <!--将str转换为大写-->
<h3>{{ script|safe }}</h3>  <!--对script不进行html转义-->

【模板的继承】

作用:模板继承可以使父模板的内容重用,子模版直接继承父模板的全部内容并可以覆盖父模板中相应的块

重写的覆盖规则:1、不重写,则按照父模板的效果显示;2、重写,则按照重写效果显示

*注意:模板继承时,服务器端的动态内容无法继承(如从视图函数调用的变量)

语法:

  • 父模板中:
    • 定义父模板的块block标签(block标签:在父模板中定义,在子模版中覆盖)
    • 用block标签标识出哪些在子模版中是允许被修改的
  • 子模版中:
    • 继承模板extends标签(写在模板文件的第一行!!)
    • 重写父模板中的内容块
<!--子模版中-->
{% extends '父模板文件' %}  <!--此句写在第一行-->

{% block block_name %}
子模版块用来覆盖父模板中block_name块的内容
{% endblock block_name %}  <!--此处的block_name可以省略不写,上面的不能省-->

样例:父模板为base.html,子模版music.html和sport.html继承base.html

base.html:

<head>
    <meta charset="UTF-8">
    <!--此处设置为子模版可覆盖内容-->
    {% block mytitle %}
    <title>主页</title>
    {% endblock %}
</head>
<body>
<a href="/music_index">音乐</a>
<a href="/sport_index">体育</a>
<br>
<!--此处设置为子模板可覆盖内容-->
{% block info %}
这是主页
{% endblock %}
<br>
<h3>有任何问题请联系1234</h3>
</body>
</html>

music.html:以下是完整代码,编辑器自带代码模板全部删除

{% extends 'base.html' %}

{% block title %}
    <title>音乐</title>
{% endblock %}

{% block info %}
欢迎来到音乐频道
{% endblock %}

sport.html:

{% extends 'base.html' %}

{% block title %}
    <title>体育</title>
{% endblock %}

{% block info %}
欢迎来到体育频道
{% endblock %}

  • 25
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值