Django框架基础5
本节知识重点:
1、判断变量值是否相等(equal)
2、extends模板继承标签
3、load加载标签或过滤器
4、模板继承的应用(block与extends)
5、路由分发函数(include)
6、url标签实现反向解析(先app_name='index',再{% url %})
7、reverse()函数实现反向解析(重定向)
8、命名空间namespace(namespace='first')
一、Django模板标签完整攻略
前面我们重点讲解了模板语言中使用频率较高到的三个标签 if、for 以及 url。
本节我们将其余标签选择性的讲解。
学习 Django 框架的时候,要学会抓住知识重点,这是提高学习效率的一种有效途径。
1、判断变量值是否相等
判断两个变量的值是否相等,也是一种很常见的需求。
我们使用 ifequal 标签来进行判断,它与 endifequal 标签成对出现,当然也可以使用 if 标签配合比较运算符来实现,所以这个标签也显的很鸡肋,Django官方的解释是,为了简化操作过程所以提供了这个标签,所以这就要看大家的喜好,自己决定是否使用它吧。
它的语法格式如下:
{% ifequal n1 n2 %}
...代码块1
{% else %}
...代码块2
{% endifequal %}
n1 与 n2 的值相等的,那么就执行代码块 1,如果不等就执行代码块 2,示例如下:
{% ifequal n1 n2 %}
<p>{{ n1 }} equal {{ n2 }}</p>
{% else %}
<p>{{ n1 }} not equal {{ n2 }} </p>
{% endifequal %}
但是 Python 的字典类型、列表类型、布尔类型,不能用在 {% ifequal %} 中。
2、extends模板继承标签
-
{% extends "base.html" %} 继承名为 "base.html" 的父模板;
-
{% extends variable %} 使用 variable 变量表示的模版。
模板继承在 Django 模板语言中也是非常重要的知识,我们将会对其做单独的讲解。
3、
load 标签用于在模板中加载自定义模板标签集或者过滤器,可以加载项目中的静态文件,格式使用如下:
{% load static %} 加载静态文件
4、
二、模板语言的注释
如同 HTML 和其他的语言例如 Python 一样,Django 模板系统也允许注释。 注释使用{# #}
的格式。
{# This is a comment #}
{% comment %}
...要被注释的内容放在两个标签中间
{% endcomment %}
在本节我们讲述模板语言中最后一个知识点,也是最重要的,那就是模板继承。
那模板继承到底是是什么呢?如何在 Django 中使用它呢?让我们一起一探究竟。
1、模板继承的概念
模板继承是 Django 模板语言中最强大的部分。模板继承使你可以构建基本的“骨架”模板,将通用的功能或者属性写在基础模板中,也叫基类模板或者父模板。子模板可以继承父类模板,子模板继承后将自动拥有父类中的属性和方,我们还可以在子模板中对父模板进行重写,即重写父模板中方法或者属性,从而实现子模板的定制。模板继承大大提高了代码的可重用性,减轻开发人员的工作量。
2、
在模板继承中最常用了标签就是 {% block %} 与 {% extends %} 标签,其中 {% block% } 标签与 {% endblock %} 标签成对出现,而 {% extends %} 放在子模板的第一行且必须是模板中的第一个标签,标志着此模板继承自父模板,它们使用方法如下所示:
#定义父模板可被重写内容
{% block block_name %}
...可以被子模板覆盖的内容
{% endblock block_name %}
#继承父模板
{% extends '父模板名称' %}
#子模板重写父模板
{% block block_name %}
...子模板覆盖后呈现的新内容
{% endblock block_name %}
首先在 templates/index 目录下定义父模板 base.html,代码如下所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}Welcome to 乔治老师的课堂 {% endblock title %}</title>
</head>
<body>
<!--区域1默认区域不可以被子模板修改-->
<p>亲爱的同学您好:</p>
<hr>
<!--区域2可以被子模板重写-->
{% block content %}
<p>这是主体内容可以被子模板重写</p>
{% endblock content %}
<hr>
<!--区域3可以被子模板重写-->
{% block footer %}
<p>这是结尾的内容也可以被重写</p>
{% endblock footer %}
</body>
</html>
{% extends 'index/base.html' %}
<!--重写title-->
{% block title %} 欢迎你学习Django教程 {% endblock %}
<!--区域1保持父模板默认状态-->
<!--对父模板的区域2进行重写-->
{% block content %}
{% for item in course %}
<li>{{ item }}</li>
{% endfor %}
{% endblock content %}
{% block footer %}
<p>最后希望<span style="color:green">{{ name }}</span>可以学有所成</p>
{% endblock footer %}
在 index/views.py 文件编写视图函数,如下所示:
# 定义父模板视图函数
def base_html(request):
return render(request, 'index/base.html')
# 定义子模板视图函数
def index_html(request):
name = 'xiaoming'
course = ['python', 'django', 'flask']
return render(request, 'index/test.html', locals())
然后更新子路由,代码如下所示:
# 127.0.0.1:8000/index/test 访问子模板
path('test/', views.index_html),
# 127.0.0.1:8000/index/base 访问父模板
path('base/', views.base_html)
在浏览器地址栏输入父模板 url 地址进行访问,得到的结果如下所示:
看看它又是如何的呢?展示结果如下所示:
我们可以看出,子模板对父模板中 {% block %} 包含的内容进行了重写覆盖,这就是模板继承应用。如果在多个模板中出现了大量复杂的代码,那么就应该考虑使用模板继承来减少重复性代码。
3、总结归纳
-
block 标签需要成对出现,使用 {{ endblock }} 作为结束标签;
-
定义 block 标签名字,子模板中具有同样名称的 block 块完成对父模板的替换;
-
子模板不需要定义父模板中的所有 block,未定义时,子模板将原样使用父模板中的内容;
-
子模板需要使用 {% extends %} 标签继承父模板,且必须是模板中的第一个标签,并放在文件的第一行;
四、Django路由反向解析与命名空间
1、路由分发函数
在实际开发过程中,一个Django 项目会包含很多的 app ,这时候如果我们只在主路由里进行配置就会显得杂乱无章,所以通常会在每个 app 里,创建各自的 urls.py 路由模块,然后从根路由出发,将 app 所属的 url 请求,全部转发到相应的 urls.py 模块中。而这个从主路由转发到各个应用路由的过程叫做路由的分发,而它的实现是使用include() 函数来完成的,如下所示:
from django.urls import path,include
from BookStore import views
urlpatterns = [path('index/',include('index.urls'))]
2、什么是反向解析
在处理业务需求的过程中,当我们遇到重定向或在模板中需要链接到其他的视图函数,在这两种场景下我们就会使用到 url 的反向解析,而不使用硬编码的方式将 url 放在模板中。这样做的优势在于当 URL 发生变化后,也无须我们更改模板中的 URL。
3、反向解析的应用
在需要解析 URL 的地方,Django 提供了不同的方式来实现 URL 反向解析:
-
-
-
在处理模型 model 类实例时:使用 get_absolute_url() 方法。
我们对前两种方法进行实例讲解,第三种方法了解即可。首先我们需要在 index/urls.py 路由文件中对 index 应用进行注册,使用如下方式来完成注册:
app_name='index' #写在开始位置即可
(1)
test/
from django.urls import path
from index import views
app_name='index'
urlpatterns=[
path('test/',views.index_html,name='detail_hello'),
]
然后在 templates/index 目录下新建 newtest.html 并编写如下代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href=" {% url 'index:detail_hello' %}">点击继续</a>
<p>一起去酒吧嗨翻天。</p>
</body>
</html>
最后在 index\views.py 编写视图函数并配置相应路由映射,如下所示:
#视图函数
def redict_url(request):
return render(request,'index/newtest.html')
#路由映射
urlpatterns=[
path('redict/',views.redict_url),
]
http://127.0.0.1:8000/index/redict/
(2)
from django.http import HttpResponseRedirect
from django.urls import reverse
#reverse函数实现反向解析重定向到我们想要的有页面
def test_to_reverse(request):
return HttpResponseRedirect(reverse('index:detail_hello'))
#在index/urls.py中为视图函数配置路由
urlpatterns=[
path('test/',views.index_html,name='detail_hello'),
path('reverse/',views.test_to_reverse)
]
最后访问 http://127.0.0.1:8000/index/reverse/ 可以直接重定向到 http://127.0.0.1:8000/index/test/。
reverse(viewname,urlconf=None,args=None,kwargs=None,current_app=None)
from BookStore import views
def test_to_reverse(request):
return HttpResponseRedirect(reverse(views.test_url))
-
urlconf:这个属性用于决定当前的反向解析使用哪个 URLconf 模块,默认是根 URLconf;
-
args:它用于传递参数,可以是元组或者列表,顺序填充 url 中的位置参数;
-
kwargs:字典类型的传参,和 args 作用一样;
-
current_app:它指定当前视图函数所在的 app,本例中是 index 应用。
URL 命名空间分为两个部分:第一,应用命名空间即使用 app_name 关联应用名字;第二,使用 namespace 用来标识一个应用的实例,主要功能是区分同一个应用中不同的实例。
下面为了让大家更好的理命名空间的概念,我们对本节的示例进行改写,首先在主路由 BookStore/urls.py 的 url 模式列表中,使用 namespace 参数给 index 应用添加命名空间。如下所示:
urlpatterns = [
path('index/',include('index.urls', namespace='first'))
]
app_name="index"
def test_to_reverse(request):
return HttpResponseRedirect(
reverse('index:detail_hello',current_app=request.resolver_match.namespace)
)
url 的反向解析是个重要的知识点,它可以帮助我们在不同应用之间实现页面的跳转以及视图的重定向,所以我们要熟练的掌握并应用它们。