文章目录
08、常用的模板标签和过滤器
上节课开始博客网站的搭建,主要是讲虚拟环境的使用,并且开始了一个 blog 的应用,这节课要讲的是常用的模板标签和过滤器。
上节课搭建 blog,我们已经写了 models 和 admin,后台管理的设置,当然我们这只是一个模型,还没有显示到前端页面,这节课开始做显示到页面
1、继续搭建blog
- models(上节课)
- admin(上节课)
- views
- urls
- templates
1、处理方法views
既然是个人博客网站,可以先不用写这么复杂,前端页面的首页就是一个博客的列表,然后点进去博客列表就可以打开具体的博客,这样的话,就至少需要两个处理方法:
在 blog/views.py 中写入如下代码:
# # C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\blog\views.py
from django.shortcuts import render_to_response, get_object_or_404 # render_to_response:用模板页面输出响应内容
from .models import Blog
# Create your views here.
# 需要两个处理方法:1.访问博客列表;2.显示具体的blog页面
def blog_list(request):
context = {}
context['blogs'] = Blog.objects.all()
return render_to_response("blog_list.html", context)
# 具体的blog页面需要传一个参数进来,这个参数就是主键id(主键pk)
def blog_detail(request, blog_pk):
context = {}
context['blog'] = get_object_or_404(Blog, pk=blog_pk)
return render_to_response('blog_detail.html', context)
2、模板页面templates
在 blog 下新建 templates(在 blog 右键点击 New Folder),在 templates 目录下,新建 blog_list.html 和 blog_detail.html(在 templates 右键点击 New File),点击新建的文件的右下角 Plain Text 选择 HTML,(输入 html,然后按 Tab 键,可以快速生成 HTML 模板)
blog\templates\blog_list.html:
<!-- C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\blog\templates\blog_list.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>我的网站</title>
</head>
<body>
{% for blog in blogs %} <!--注意,这里的blogs是从views.py里blog_list的context['blogs'] = Blog.objects.all()传入的变量,传入到页面模板进来才有这个blogs-->
<h3>{{ blog.title }}</h3> <!--blog.title/blog.content是从模型models.py里面得到-->
<p>{{ blog.content }}</p>
{% endfor %}
</body>
</html>
blog\templates\blog_detail.html:
<!-- C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\blog\templates\blog_detail.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{{ blog.title }}</title><!--注意,这里blog.title的blog是从views.py里blog_detail的context['blog'] = get_object_or_404(Blog, pk=blog_pk)传入的变量-->
</head>
<body>
<h3>{{ blog.title }}</h3>
<p>{{ blog.content }}</p>
</body>
</html>
3、访问路由设置urls
这样的话,我们模板页面(blog_list.html和blog_detail.html)有了,处理方法(views.py)有了,还需要一个访问,访问路由设置
在 blog 下新建文件 urls.py,这个文件是作为 views 的 url,写入如下代码:
blog\urls.py:
# # C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\blog\urls.py
from django.urls import path
from . import views
'''
http://localhost:8000/blog/1 # 访问具体某篇文章 # http://localhost:8000/blog/ # 博客列表
http://localhost:8000 # 打开首页。总路由
'''
# start with blog
urlpatterns = [
# http://localhost:8000/blog/1
path('<int:blog_pk>', views.blog_detail, name='blog_detail'),
]
设置总的路由:在 mysite/mysite/urls.py 中:
mysite\urls.py:
# # C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\mysite\urls.py
from django.contrib import admin
from django.urls import path, include
from blog.views import blog_list
urlpatterns = [
path('', blog_list, name='home'), # 首页处理方法对应的路由设置
path('admin/', admin.site.urls),
path('blog/', include('blog.urls')), # 应用分支路由设置
]
4、访问
我们在 mysite_env 目录下打开 cmd,输入Scripts\activate
启动一下虚拟环境,cd mysite
,python manage.py runserver
启动本地服务,访问 http://localhost:8000,可以看到只有一条博客,没有其他内容,
5、新增博客
这个作为首页不是很清晰,我们可以进一步做一下其他改进,在 blog_list.html 中:
blog\templates\blog_list.html :
<!-- C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\blog\templates\blog_list.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>我的网站</title>
</head>
<body>
<div>
<a href="{% url 'home' %}">
<h3>个人博客网站</h3>
</a>
</div>
<hr>
{% for blog in blogs %} <!--注意,这里的blogs是从views.py里blog_list的context['blogs'] = Blog.objects.all()传入的变量,传入到页面模板进来才有这个blogs-->
<a href="{% url 'blog_detail' blog.pk %}"> <!--url+别名+参数(这里是主键)-->
<h3>{{ blog.title }}</h3> <!--blog.title/blog.content是从模型models.py里面得到-->
</a>
<p>{{ blog.content }}</p>
{% endfor %}
</body>
</html>
blog\templates\blog_detail.html:
<!-- C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\blog\templates\blog_detail.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{{ blog.title }}</title><!--注意,这里blog.title的blog是从views.py里blog_detail的context['blog'] = get_object_or_404(Blog, pk=blog_pk)传入的变量-->
</head>
<body>
<div>
<a href="{% url 'home' %}">
<h3>个人博客网站</h3>
</a>
</div>
<h3>{{ blog.title }}</h3>
<p>{{ blog.content }}</p>
</body>
</html>
那如果我们登陆进入后台管理 http://localhost:8000/admin,多加一条博客
刷新 http://localhost:8000
6、统计博客数量
过滤器 length
那如果我们想要一目了然的看到有多少条博客,这里就要用到一个标签帮我们去统计,有两种做法:
(1)在 blog_list.html 中加上一行代码:{{ blogs | length}}
blog\templates\blog_list.html:
<!-- C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\blog\templates\blog_list.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>我的网站</title>
</head>
<body>
<div>
<a href="{% url 'home' %}">
<h3>个人博客网站</h3>
</a>
</div>
<hr>
<p>一共有{{ blogs | length}} 篇博客</p><!--这是一个过滤器-->
{% for blog in blogs %} <!--注意,这里的blogs是从views.py里blog_list的context['blogs'] = Blog.objects.all()传入的变量,传入到页面模板进来才有这个blogs-->
<a href="{% url 'blog_detail' blog.pk %}"> <!--url+别名+参数(这里是主键)-->
<h3>{{ blog.title }}</h3> <!--blog.title/blog.content是从模型models.py里面得到-->
</a>
<p>{{ blog.content }}</p>
{% endfor %}
</body>
</html>
(2)【这个方法比较多余,因为已经有方法一了】在 views.py 中添加代码context['blogs_count'] = Blog.objects.all().count()
,然后在 blog_list.html 调用这个变量
blog/views.py:
# # C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\blog\views.py
def blog_list(request):
context = {}
context['blogs'] = Blog.objects.all()
context['blogs_count'] = Blog.objects.all().count()
return render_to_response("blog_list.html", context)
那如果我们首页是0篇博客(先在后台删掉前面的两篇博客),我们想要设置一个提示信息:{% empty %}<p>-- 暂无博客,敬请期待 --</p>
blog\templates\blog_list.html:
<!-- C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\blog\templates\blog_list.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>我的网站</title>
</head>
<body>
<div>
<a href="{% url 'home' %}">
<h3>个人博客网站</h3>
</a>
</div>
<hr>
<!-- <p>一共有{{ blogs_count}}篇博客</p> -->
{% for blog in blogs %} <!--注意,这里的blogs是从views.py里blog_list的context['blogs'] = Blog.objects.all()传入的变量,传入到页面模板进来才有这个blogs-->
<a href="{% url 'blog_detail' blog.pk %}"> <!--url+别名+参数(这里是主键)-->
<h3>{{ blog.title }}</h3> <!--blog.title/blog.content是从模型models.py里面得到-->
</a>
<p>{{ blog.content }}</p>
{% empty %}
<p>-- 暂无博客,敬请期待 --</p>
{% endfor %}
<p>一共有{{ blogs | length}} 篇博客</p><!--这是一个过滤器-->
</body>
</html>
7、控制显示内容的长度
过滤器 truncatechars
如果我们首页中的博客的内容很长,我们希望只显示前三十字或者前五十字符,这里可以通过过滤器truncatechars:50
、truncatewords:30
去处理,代码{{ blog.content | truncatechars:50}}
修改blog\templates\blog_list.html :
<!-- C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\blog\templates\blog_list.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>我的网站</title>
</head>
<body>
<div>
<a href="{% url 'home' %}">
<h3>个人博客网站</h3>
</a>
</div>
<hr>
<!-- <p>一共有{{ blogs_count}}篇博客</p> -->
{% for blog in blogs %} <!--注意,这里的blogs是从views.py里blog_list的context['blogs'] = Blog.objects.all()传入的变量,传入到页面模板进来才有这个blogs-->
<a href="{% url 'blog_detail' blog.pk %}"> <!--url+别名+参数(这里是主键)-->
<h3>{{ blog.title }}</h3> <!--blog.title/blog.content是从模型models.py里面得到-->
</a>
<p>{{ blog.content | truncatechars:50}}</p> <!--这是一个过滤器-->
{% empty %}
<p>-- 暂无博客,敬请期待 --</p>
{% endfor %}
<p>一共有{{ blogs | length}} 篇博客</p><!--这是一个过滤器-->
</body>
</html>
8、完善信息:
过滤器 date
接下来我们完善页面信息:
(1)blog_detail 博客详细信息完善:显示作者、发表日期、博客分类等内容。日期这里,如果需要对日期进行格式化显示,需要用到一个过滤器date
blog\templates\blog_detail.html:
<!-- C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\blog\templates\blog_detail.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{{ blog.title }}</title><!--注意,这里blog.title的blog是从views.py里blog_detail的context['blog'] = get_object_or_404(Blog, pk=blog_pk)传入的变量-->
</head>
<body>
<div>
<a href="{% url 'home' %}">
<h3>个人博客网站</h3>
</a>
</div>
<h3>{{ blog.title }}</h3>
<p>作者:{{ blog.author }}</p>
<p>发表日期:{{ blog.created_time | date:"Y:m:d G:n:s" }}</p> <!--这是一个过滤器--><!--h:n:s:12小时制;G:n:s/H:n:s:24小时制。这些内容都是可以查看官网找到-->
<p>分类:{{ blog.blog_type }}</p>
<p>{{ blog.content }}</p>
</body>
</html>
(2)博客分类这里,我们想要点击分类“随笔”,就会将随笔下面的所有文章显示出来:
修改blog\urls.py,新增path('type/<int:blog_type_pk>', views.blogs_with_type, name='blogs_with_type')
:
# # C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\blog\urls.py
from django.urls import path
from . import views
'''
http://localhost:8000/blog/1 # 访问具体某篇文章 # http://localhost:8000/blog/ # 博客列表
http://localhost:8000 # 打开首页。总路由
'''
# start with blog
urlpatterns = [
# http://localhost:8000/blog/1
path('<int:blog_pk>', views.blog_detail, name='blog_detail'),
path('type/<int:blog_type_pk>', views.blogs_with_type, name='blogs_with_type'), # 这里前面需要加上type/,不然就会和上一条url重复了
]
修改mysite_env\mysite\blog\views.py,新增blogs_with_type
方法:
# # C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\blog\views.py
from django.shortcuts import render_to_response, get_object_or_404 # render_to_response:用模板页面输出响应内容
from .models import Blog, BlogType # 引入BlogType这个模型
# Create your views here.
# 需要两个处理方法:1.访问博客列表;2.显示具体的blog页面
def blog_list(request):
context = {}
context['blogs'] = Blog.objects.all()
# context['blogs_count'] = Blog.objects.all().count()
return render_to_response("blog_list.html", context)
# 具体的blog页面需要传一个参数进来,这个参数就是主键id(主键pk)
def blog_detail(request, blog_pk):
context = {}
context['blog'] = get_object_or_404(Blog, pk=blog_pk)
return render_to_response('blog_detail.html', context)
def blogs_with_type(request, blog_type_pk):
context = {}
blog_type = get_object_or_404(BlogType, pk=blog_type_pk)
context['blogs'] = Blog.objects.filter(blog_type=blog_type) # 筛选
context['blog_type'] = blog_type
return render_to_response("blogs_with_type.html", context)
新增blog\templates\blogs_with_type.html:
<!-- C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\blog\templates\blogs_with_type.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{{blog_type.type_name}}</title> <!--blog_type来自于views.py中blogs_with_type的context['blog_type'] = blog_type这里;blog_type.type_name来自于models.py中BlogType里面的type_name -->
</head>
<body>
<div>
<a href="{% url 'home' %}">
<h3>个人博客网站</h3>
</a>
</div>
<hr>
<h3>{{ blog_type.type_name }}</h3>
{% for blog in blogs %}
<a href="{% url 'blog_detail' blog.pk %}">
<h3>{{ blog.title }}</h3>
</a>
<p>{{ blog.content | truncatechars:50}}</p>
{% empty %}
<p>-- 暂无博客,敬请期待 --</p>
{% endfor %}
<p>一共有{{ blogs | length}} 篇博客</p>
</body>
</html>
修改blog\templates\blog_detail.html:
<!-- C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\blog\templates\blog_detail.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{{ blog.title }}</title><!--注意,这里blog.title的blog是从views.py里blog_detail的context['blog'] = get_object_or_404(Blog, pk=blog_pk)传入的变量-->
</head>
<body>
<div>
<a href="{% url 'home' %}">
<h3>个人博客网站</h3>
</a>
</div>
<h3>{{ blog.title }}</h3>
<p>作者:{{ blog.author }}</p>
<p>发表日期:{{ blog.created_time | date:"Y:m:d G:n:s" }}</p> <!--这是一个过滤器--><!--h:n:s:12小时制;G:n:s/H:n:s:24小时制。这些内容都是可以查看官网找到-->
<p>分类:
<a href="{% url 'blogs_with_type' blog.blog_type.pk %}">
{{ blog.blog_type }}
</a>
</p>
<p>{{ blog.content }}</p>
</body>
</html>
完成代码后,我们先登录后台,新增几条博客,然后刷新网站页面:
访问网站页面:
2、常用的模板标签
- 循环:
for
- 条件:
if
(可逻辑判断)、ifequal
、ifnotequal
- 链接:
url
- 模板嵌套:
block
、extends
、include
- 注释:
{# #}
我们上面可以讲过了for
和url
和include
注释{# #}
:
3、常用的过滤器
- 日期:
date
- 字数截取:
truncatechars
、truncatechars_html
、truncatewords
、truncatewords_html
- 是否信任html:
safe
- 长度:
length
可参考:http://docs.djangoproject.com/en/2.0/ref/templates/builtins/