项目简介
- 项目是基于Django2.2+ubuntu16(HuaWei cloud)+python3.6开发的初学者博客网站项目
- 网站上线使用Apache2 Web服务 (后续更新)
- 此项目基本按照教材《Django架站的16堂课》所建,如需教材以及
github源码链接
可关注公众号【小灰啾】回复"Django教材
"获取! - 效果图如下图所示:
目录
文章目录
- 项目简介
- 目录
- 项目搭建过程
- 环境搭建
- 从零开始搭建
- 1. 进入虚拟环境
- 2. pip安装django2.2
- 3. 创建一个空白项目
- 4. 测试空项目
- 5. 创建个人博客
- 1) 修改settings.py
- 2) 建立数据库
- 3) 启用admin界面
- 4) 读取数据库内容
- 5) 建立网页输出模板template
项目搭建过程
环境搭建
-
ubuntu16安装python3.6
-
安装git
-
安装python3.6
-
安装pip3+virtualenv
-
clone repositories
-
安装python库
-
python manage.py runserver 0.0.0.0:8000
从零开始搭建
1. 进入虚拟环境
执行环境搭建
到第4后,进入虚拟环境:
source venvpy3/bin/activate
2. pip安装django2.2
pip install django==2.2
检查是否安装到虚拟环境中
pip list
如果没有安装到虚拟环境中安装到了全局中,可以指定pip库
此时可以通过 venv\scripts\python -m pip -V 或 venv\scripts\pip -V 指定pip命令的路径。
下载时同样通过venv\scripts\python -m pip install 进行下载。
检查是否安装到虚拟环境中
pip list
如果没有安装到虚拟环境中安装到了全局中,可以指定pip库
此时可以通过 venv\scripts\python -m pip -V 或 venv\scripts\pip -V 指定pip命令的路径。
下载时同样通过venv\scripts\python -m pip install 进行下载。
3. 创建一个空白项目
django-admin startproject myblogcd myblogpython manage.py startapp mainsitecd ..tree myblogmyblog/├── mainsite│ ├── admin.py│ ├── apps.py│ ├── __init__.py│ ├── migrations│ │ └── __init__.py│ ├── models.py│ ├── tests.py│ └── views.py├── manage.py└── myblog├── __init__.py├── __pycache__│ ├── __init__.cpython-36.pyc│ └── settings.cpython-36.pyc├── settings.py├── urls.py└── wsgi.py
4. 测试空项目
创建之前需要migrate一下
(venvpy3)test/myblog$ python manage.py migrate(venvpy3) lhw@ecs:~/literaryworld/test/myblog$ python manage.py runserver 0.0.0.0:9000
网页登录你的公网ip:9000,报错,提示该ip被拒绝访问,修改~/test/myblog/myblog/setting.py
建议使用
Notepad++
修改
将上述文档修改成下面:
ALLOWED_HOSTS = [] #原数组ALLOWED_HOSTS = ['*',]#修改后,'*'表示允许所有ip访问该网页,也可填写具体ip
修改后保存再执行
(venvpy3) lhw@ecs:~/literaryworld/test/myblog$ python manage.py runserver 0.0.0.0:9000
刷新界面,表示成功!
5. 创建个人博客
1) 修改settings.py
settings.py是此网站的系统设计所在位置,新建立的网站都要先开放此档案,做些编辑设定工作。而真正网站所有的运作的逻辑,则是在使用startapp mainsite建立出来的APP文件夹中。使用这种方式,主要目的是让网站的每一个主要功能都成为一个单独的模组,方便网站的开发者可以在不同的网站中重复使用,也就是复用。
首先,我们将之前建立的APP模组mainsite加进去:(在settings.py的INSTALLED_APPS列表中)
# Application definitionINSTALLED_APPS = ['django.contrib.admin', #内置后台管理系统'django.contrib.auth', #内置的用户认证系统'django.contrib.contenttypes', #记录项目中所有的model元数据(Django的orm框架)'django.contrib.sessions', #会话功能,用于标识当前访问网站的用户身份,记录相关的用户信息'django.contrib.messages', #消息提示功能'django.contrib.staticfiles', #查找静态资源路径'mainsite', #项目创建的mainsite app'markdown_deux', #markdown支持
]
将系统默认时区改为中国时区:
LANGUAGE_CODE = 'zh-Hans' #2.0改版后zh_Hans改为zh-HansTIME_ZONE = 'Asia/Shanghai'
另外,在预设的情景下,Django会使用SQLite来储存资料库内容,在使用以下命令时,会产生叫做db.sqlite3的文档
(venvpy3) lhw@ecs:~/literaryworld/test/myblog$ python manage.py makemigrations
(venvpy3) lhw@ecs:~/literaryworld/test/myblog$ python manage.py migrate
之后,所有在此网站中新增到数据库的数据,都会被放在db.sqlite3这个文件中,这是一个简化过的文件型SQL开放式数据库系统,如果网站要搬移,一定带上这个文件。
2) 建立数据库
在预设的情况下,Django的数据库是以Model的方式来操作,也就是不直接操作数据库及数据表,而是以class类的方式建立出Model,然后再透过对Model的操作,连接到数据库的目的。
因此,在Django要使用数据库,有以下步骤:
- 在models.py中定义所需要使用的类别(继承自models.Model)
- 详细地设定每一个在类中的变量
- 使用python manage.py makemigration mainsite建立数据库和Django间的中间档案
- 使用python manage.py migrate同步更新数据库的内容
- 在程序中使用python的语法操作所定义的数据类别,等于是在操作数据库中的数据表
建立博客,需要一个用来存储文章的数据表,所以,就需要修改mainsite/models.py的内容。一开始,models.py的内容如下:
from django.db import models# Create your models here.
修改为如下内容:
from django.db import models
from django.utils import timezone
# Create your models here.class Post(models.Model):title = models.CharField(max_length=200) #文章标题slug = models.CharField(max_length=200) #文章网址body = models.TextField() #文章内容pub_date = models.DateTimeField(default=timezone.now) #发表日期class Meta:ordering = ('-pub_date',) #根据发表日期排序#提供此类别所产生的资料项目,以文章标题当做是显示的内容,Unicode标题可以支持中文标题(在python3中使用str)def __str__(self): return self.title
在这里主要建立一个叫做Post的类别(会在数据库中会有一个对应的数据表),在此类中包括几个项目,title是用来表示文章标题,而slug则是文章的网址,body则是文章的内容,最后pub_date则是本文发表的时间。至于class Meta内的设定,则是指文章要显示的顺序是以pub_date为依据,最后 __ str __ 则是提供此类别所产生的数据项目,以文章标题作为显示内容,增加操作过程的可读性。要提醒的是在django 2.0以后,使用str才能正常支持中文,在之前版本可能需要使用__ unicode __。
pub_date是以timezone.now的方式让它自动产生,这需要一个pytz模组才行。
此时即可在程序中直接操作此数据库了。但是为了方便,需要启用django提供的admin界面来操作,会更加方便。
3) 启用admin界面
admin是Django预设的数据库内容管理界面,在使用之前,有几个步骤,第一步,是建立一个管理者的账号及密码,如下所示:
(venvpy3) lhw@ecs-sn3-medium-2-linux-20200115102149:~/literaryworld/test/myblog$ python manage.py createsuperuser
用户名 (leave blank to use 'lhw'): admin
电子邮件地址:
Password:
Password (again):
Superuser created successfully.
接着,将上一步定义的Post纳入管理,需要修改mainsite/admin.py,原本是如下所示的内容:
from django.contrib import admin# Register your models here.
修改为如下内容:
from django.contrib import admin
from .models import Post
# Register your models here.
#先引入Post类别,然后再透过admin.site.register注册即可。
#然后通过http://host:8000/admin,即可登录
class PostAdmin(admin.ModelAdmin):list_display=('title','slug','pub_date')
admin.site.register(Post,PostAdmin)
先引入我们的Post类别,通过admin.site.register注册即可。完成设定之后再次启用此网站,然后通过浏览器连接到http://localhost:9000/admin,就可以看到下面所示界面
此时在admin.py中加入PostAdmin类的代码(自订Post显示的方式类别,继承自admin.ModelAdmin),让文章在显示的时候,除了title之外,还可以再加上张贴的日期和时间等内容
在Posts类增加数据表,增添完文章后点击右下角保存,
保存四五篇诗文之后,内容中英文皆可,但是slug要使用英文或数字,而且中间不要使用任何符号以及空白字元,显示如下:
4) 读取数据库内容
资料库中有了文章内容之后,接下来就是读取这些资料,然后在网站的首页中把它们显示出来。
MTV:
M model -> models.py; T template -> template文件夹; V view -> views.py;
models.py负责定义要存取的资料类型,以class类别方式定义,后端Django自动把 设定对应到资料库系统中
如果将资料拿出来,或者如何存进去的这些程式逻辑,则在views.py中处理
如何把这些取到的资料用美观有弹性的方式输出,则是在Template中加以处理
因此,先打开mainsite/view.py
,一开始的内容如下:
from django.shortcuts import render
# Create your views here.
改成下列内容:
#from django.shortcuts import render
from django.http import HttpResponse
from .models import Post
from django.template.loader import get_template
from datetime import datetime
from django.shortcuts import redirect
# Create your views here.#考虑到有可能会有自行输入错误网址以至于找不到文章,除了在Post.objects.get(slug=slug)搜索文章时加上例外处理,
#也在发生例外的时候以redirect('/')方式直接返回首页'''
# 将models.py中自定义的model引入,然后使用Post.objects.all()取得所有的资料项目,然后用for遍历所有内容
#透过HttpResponse输出到网页中
##
#再次理中建立homepage函数获取所有文章,并通过遍历把内容存储到一个变量post_lists中,再使用
#return HttpResponse(post_lists)输出到网页上
#
#设置完函数后,透过urls.py来负责网址和程序间的对应工作。开放urls.py,分别引入来自于views.py的
#homepage函数并以url对应之
def homepage(request):posts = Post.objects.all()post_lists = list()for count,post in enumerate(posts):post_lists.append("No.{}:".format(str(count))+str(post)+"<hr>")post_lists.append("<small>"+str(post.body)+"</small><br><br>")return HttpResponse(post_lists)
'''def homepage(request): #主页面template = get_template('index.html')posts = Post.objects.all()now = datetime.now()html = template.render(locals())return HttpResponse(html)def showpost(request,slug): #诗歌界面template = get_template('post.html')try:post = Post.objects.get(slug=slug) #匹配传入参数与资料库中的slugif post!= None:html = template.render(locals())return HttpResponse(html)except:return redirect('/') #错误直接返回首页
在此,我们使用homepage来做为我们网站的主界面,template = get_template('index.html')
获取模板index.html
的信息,并通过Post.objects.all()
获取数据库中所有项目,通过locals()
将所有变量打包成键值对,通过template.render(locals())
将变量自动填充到html模板中,然后通过return HttpResponse(html)
,输出到客户端的浏览器界面中。
其中showpost类似,只是仅匹配request对应文章slug对应的文章内容,并填充到对应的post.html
模板中去显示文章。(模板我们后面介绍)
有了这些函数,需要透过urls.py
来负责网址和程序间的对应工作,否则,无法匹配到对应的函数。打开urls.py
,分别引入来自views.py
的homepage和showpost函数,如下所示:
from django.contrib import admin
from django.urls import path
from django.conf.urls import include,url
from mainsite.views import homepage,showpost#其中,url(r'^$',homepage)这一行中,^表示字符串开始处,$表示字符串结尾处,
#两者接在一起就是,当有使用者浏览了网址而没加上任何字符串的时候即(根网址)
#就去呼叫homepage这个函数
#
urlpatterns = [url(r'^$',homepage),url(r'^post/(\w+)$',showpost), #通过r'^post/(\w+)$'将post/后面的字符找出来并将作为第二个参数传递给showpost,第一个参数是requestpath('admin/', admin.site.urls),
]
其中,url(r’^$’,homepage)这一行中,^表示字符串开始处,$表示字符串结尾处,两者接在一起就是,当有使用者浏览了网址而没加上任何字符串的时候即(根网址)就去呼叫homepage这个函数,showpost类似。
5) 建立网页输出模板template
每一个输出的网页都可以变为一个或一个以上对应的模板,而这些模板是以.html的文件形式储存在指定文件夹中(一般命名为templates),当网站有资料需要输出的时候,再通过渲染函数(render)把资料放到模板指定位置中,得到结果 再交给HttpResponse输出给浏览器。步骤如下所示:
- 在setting.py中设定模板资料夹的位置
- 在urls.py建立网址和views.py中函数对应的关系
- 建立.html档案(例如index.html),做好排版并安排资料要放的位置
- 执行程序,以
objects.all()
在views.py
取得资料,并放入变量中,例如posts- 以render函数,把资料(例如posts)送到指定模板文件(如index.html)中
a. 首先在~/test/myblog
文件夹中创建templates
和static
文件,templates
文件夹用来存放基础html模板如header.html、footer.html、base.html等基础模板,static
文件夹用来存放静态加载文件,如images
等;
b. 在~/test/myblog/mainsite
文件夹中创建templates
作为项目APP mainsite
的专属html模板
建立文件夹后文件结构如下所示:
(venvpy3) lhw@ecs-sn3-medium-2-linux-20200115102149:~/literaryworld/test$ tree myblog/
myblog/
├── db.sqlite3
├── mainsite
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── __init__.py
│ │ └── __pycache__
│ │ ├── 0001_initial.cpython-36.pyc
│ │ └── __init__.cpython-36.pyc
│ ├── models.py
│ ├── __pycache__
│ │ ├── admin.cpython-36.pyc
│ │ ├── __init__.cpython-36.pyc
│ │ ├── models.cpython-36.pyc
│ │ └── views.cpython-36.pyc
│ ├── templates
│ ├── tests.py
│ └── views.py
├── manage.py
├── myblog
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-36.pyc
│ │ ├── settings.cpython-36.pyc
│ │ ├── urls.cpython-36.pyc
│ │ └── wsgi.cpython-36.pyc
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── static
└── templates9 directories, 24 files
Templates
然后将此文件夹加到settings.py
的TEMPLATES数组里面,如下所示:
TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates','DIRS': [os.path.join(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',],},},
]
静态文件
而在布局网站的时候不可避免加载一些图片或者.css或者是.js文件。一般,图形文件放在images文件夹下,而.css和.js文件会被放在css和js文件夹下。传统网站系统,只要指定这些文件夹在网址上,就可以顺利存取。但是对.py文件来说是属于不需要被另外处理的静态文件,为了网站运作效率,Django将这一类型的文档统称为static file(静态文件)
,另外加以安排。因此为了能够在网站中顺利存取这些文件,首先在setting.py
中特别指定静态文件要放置的位置。我们将这些文档(.js, .css, .jpg, .png等)都放在static文件夹下,图片文件放到images子目录,.css放到css子目录等。在settings.py
加入以下代码:
STATIC_URL = '/static/'
STATICFILES_DIRS=[os.path.join(BASE_DIR,'static'),
]
共用模板
每一个网站在每一页都会有一些共同的元素加以强调风格,如果将共同的部分独立出来成为另外一个文档,在使用时加以调用将使建站更加快速有效。
而在本次网站,采用以下.html文件:
文件名称 | 文件说明 |
---|---|
base.html | 网站的基础模板,提供网站的主要设计外观风格 |
header.htm | 网站中每一个网页共用的标题元素,通常是放置网站logo的地方 |
footer.html | 网站中每一个网页的共用页尾,用来放置版权声明或是其他参考咨询 |
index.html | 此范例网站的首页 |
post.html | 此范例网站用来显示单篇文章的网页 |
base.html
base.html
主要功能是构建网页的基础框架和外观风格。base.html
的内容如下:
<!-- base.html -->
<!DOCTYPE html>
<html>
<head><meta charset='utf-8'><title>{% block title %}{% endblock %}</title><!--<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"><script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>--><link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css"><script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script><script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head><body>
<!--在bootstrap中,规定了每一行都被分为了固定的12个栅栏,每一个栅栏都有自己的宽度。如果你的div用了container的样式,
那么它的宽度最大也大不过12个栅栏总共的最大宽度。而,当你的div用了container-fluid的样式,它会无视12个栅栏的规定,根据屏幕自动适应自动填充。
(当然,宽度要设置为width:100%)。
--><div class='container-fluid'>{% include 'header.html' %}<div class='row'><div class='col-sm-4 col-md-4'> <!--行分为12列.col-md-xx 数字所占列数--><div class='panel panel-default'><div class='panel-heading'> <!--带 title 的面板标题--><h3>MENU</h3></div><div class='panel-body'><!--在任何面板中包含列表组,通过在 <div> 元素中添加 .panel 和 .panel-default 类来创建面板,并在面板中添加列表组--><div class='list-group'><a href='/' class='list-group-item'>HOME</a><a href='https://www.baidu.com/' class='list-group-item' target='_blank'>百度</a><a href='http://www.nlc.cn/' class='list-group-item' target='_blank'>国家图书馆</a><a href='https://github.com/liu6010/myblog' class='list-group-item' target='_blank'>github</a></div></div></div></div><div class='col-sm-8 col-md-8'> <!--行分为12列.col-md-xx 数字所占列数--><div class='panel panel-default'><div class='panel-heading'> <!--带 title 的面板标题-->{% block headmessage %}{% endblock %}</div><div class='panel-body'>{% block content %}{% endblock %}</div><!--在面板中添加脚注,只需要把按钮或者副文本放在带有 class .panel-footer 的 <div> 中即可。--><div class='panel-footer'>{% include 'footer.html' %}</div></div></div></div></div>
</body>
</html>
在此例中,就是一般的html文件,再加上{% block title %}
的模板命令,在这些模板指令中,没有意外,使用include 'base.html'
(此例引入base模块)即可引入指定的模板文件,在base.html
中的<body></body>
中引入了{% include 'header.html' %}
和{% include 'footer.html' %}
。此外通过block指令可以在后面加上此block的名称,也就是到时候在index.html
中要填入内容的位置。在此base.html
中,分别在适当的地点指定了title
,headmessage
和content
。因为在base.html
指定了这3个区块,所以接下来继承此base.html
的任何文档都要提供这三个区块的内容才行。
同时随着HTML5和CSS3和Javascript的功能日益复杂,一个网站不可能一点一点自己设计,大部分使用一些现成的网页框架,直接套用并修改后完成。免费的网页框架不少,但是Bootstrap最受欢迎,可以直接下载到本地端加以连接执行,也可以直接利用CDN连接方式套用。在</head>
前添加一下代码:
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css"><script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script><script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
关于bootstrap栅栏系统css中的理解:
<div class="container"><div class="row"><div class="col-md-4">col-md-4</div><div class="col-md-4">col-md-4</div><div class="col-md-4">col-md-4</div><!-- 说明:每row行共12列,分个3div,每个div平占4列,即3个*4列=12列 --></div><div class="row"><div class="col-md-4">col-md-4</div><div class="col-md-8">col-md-8</div><!-- 说明:每row行共12列,分个2div,第1个div占4列,第2个div则占8列,即4列+8列=12列 --></div><div class="row"><div class="col-md-3">col-md-3</div><div class="col-md-6">col-md-6</div><div class="col-md-3">col-md-3</div><!-- 说明:每row行共12列,分个3div,每1,3个div占3列,第2个div则占6列,即3列+6列+3列=12列 --></div>
</div>
<!--混用<div class="col-xs-12 col-sm-9 col-md-6 col-lg-3">测试</div>
-->
Bootstrap参数 | 含义 |
---|---|
col-sm-** | 平板 - 屏幕宽度等于或大于 576px |
col-md-** | 桌面显示器 - 屏幕宽度等于或大于 768px |
col-lg- ** | 大桌面显示器 - 屏幕宽度等于或大于 992px |
col-xl- ** | 超大桌面显示器 - 屏幕宽度等于或大于 1200px |
container-fluid | 无视12个栅栏的规定,根据屏幕自动适应自动填充。 |
container | 它的宽度最大也大不过12个栅栏总共的最大宽度 |
row | 行,每一行可划分为12列 |
panel panel-default | 创建一个基本的面板,只需要向 元素添加 class .panel-default 即可 |
panel-heading | 带标题的面板(panels) |
panel-body | 面板内容 |
panel-footer | 面板脚注 |
list-group | 面板中添加列表组 |
list-group-item | 在列表组list-group 的 标签中通过class = "list-group-item"创建列表 |
index.html
接下来看看index.html
的内容,主要功能是显示网站的主页面,并显示文章的标题、摘要和发表日期:
<!-- index.html 主页面文件-->
{% extends 'base.html' %}
{% block title %}欢迎来到文学天地{% endblock %}
{% block headmessage %}<h3 style='font-family:楷体;'>本站文章列表</h3>
{% endblock %}
{% block content %}{% for post in posts %}<div class='panel panel-default'><div class='panel-heading'><p style='font-family:宋体;font-size:pt;font-weight:bold;'><a href='/post/{{post.slug}}'>{{post.title}}</a></p> </div><div class='panel-body' style='background-color:#ffffdd'><p>{{post.body|truncatechars:40}} <!--主页面显示文章摘要,取文章前40个字符(过滤器)--></p></div><div class='panel-footer' style='background-color:#efefef'><p>发布时间:{{post.pub_date|date:"Y-m-d, h:m:s"}} <!--现在时刻--></p></div></div><br>{% endfor %}
{% endblock %}
如上所述,文件开头以{% extends 'base.html' %}
指定要继承的文件为base.html
,然后下方就以
{% block title %}{% endblock %}
分别指出3个区块要填写的内容;其中代码中posts
参数由 [4) 读取数据库内容](#4 读取数据库内容) 中的views.py
中def homepage(request)
导入:
def homepage(request):template = get_template('index.html')posts = Post.objects.all()now = datetime.now()html = template.render(locals())return HttpResponse(html)
通过<a herf>
这个标签取出post.slug
建立为连接网址,并放在post/
之下,如拼接成http://121.36.56.144:9000/post/baigui01
;通过点击文章标题,发送POST请求,前往urls.py
利用正则表达式将请求链接中的post.slug(如,baigui01)找出来并将作为第二个参数传递给views.py
中的def showpost(request,slug)
的slug参数,匹配参数后渲染相关的.html文件,即post.html
:
def showpost(request,slug):template = get_template('post.html')try:post = Post.objects.get(slug=slug) #匹配传入参数与资料库中的slugif post!= None:html = template.render(locals())return HttpResponse(html)except:return redirect('/') #错误直接返回首页
显示文章摘要和特定的日期显示格式,这就需要Django中的filter过滤器,指定过滤器的方式在变量之后加上"|"即可,如index.html
中的{{post.body|truncatechars:40}}
显示文章摘要,下列给出几个常用的过滤器:
名称 | 用途 | 示例 |
---|---|---|
capfirst | 把第一个字母改为大写 | {{value|capfirst}} |
center | 把字符串内容置中 | {{value|center:“12”}} |
cut | 把字符串中指定的字元移除 | {{value|cut:""}} |
date | 指定日期时间的输出格式 | {{value|date:“d M Y”}} |
linebreaksbr | 置换"\n"为<br/> | {{value|linebreaksbr}} |
linenumber | 为每一行字符串上加上行号 | {{value|linenumber}} |
lower | 把字符串转换为小写 | {{value|lower}} |
random | 把前面的串列元素使用随机的方式任意一个输出 | {{value|random}} |
striptags | 把所有的HTML标记全部移除 | {{value|striptags}} |
upper | 把字符串转为大写 | {{value|upper}} |
wordcount | 计算字数 | {{value|wordcount}} |
truncatechars | 截取指定字数的字元 | {{value|truncatechars:40}} |
safe | 加入safe后可是使文章内的所有html语言可以解读出来 | {{value|safe}} |
post.html
post.html
,功能是详细显示文章内容。代码如下:
<!-- post.html 文章显示-->
{% extends 'base.html' %}
{% block title %}{{post.title}} - 文学天地{% endblock %}
{% block headmessage %}<h3 style='font-family:楷体;'>{{post.title}}</h3>
{% endblock %}
{% block content %}<p style='font-family:宋体;font-size:12pt;letter-spacing:2pt;'>{{post.body|safe}}<!--加入|safe后可是使文章内的所有html语言可以解读出来--></p>
{% endblock %}
理论相同,通过def showpost(request,slug)
函数将变量导入到post.html
中,并将文章的标题和内容显示出来。
header.html和footer.html
header.html
代码如下:
<!-- header.html -->
{% load staticfiles %}
<div class='well'><img src="{% static 'images/literary_world.jpg' %}" width="100" height="100"><span style='font-family:宋体;font-size:40pt;font-weight:700;'>欢迎来到文学天地</span><!--Well 是一种会引起内容凹陷显示或插图效果的容器 -->
</div>
此文档需要留意的地方就是第二行{% load staticfiles %}
只需要使用一次,提醒Django去载入所有的静态文件,这一行指令在同一个文件里只要使用一次即可。而在真正引入图片的地方使用{% load staticfiles %}
这个模板语言,Django会依照当时的执行环境把此文件的可存取网路位址传给浏览器。
footer.html
代码如下:
<!-- footer.html -->
{% block footer %}{% if now %}<p style='font-family:宋体;'>时间:{{now}}</p>{% else %}<a style='font-family:楷体;' href='/'>回首页</a><p style='font-family:宋体;'>本文取自网络,如有侵权请来信通知下架...</p>{% endif %}
{% endblock %}
在footer.html
中我们使用了一个模板技巧{% if now %}
,它是用来判断now这个变量是否有内容的指令,如果有就显示现在时刻,如果没有就显示版权声明。主要原因是,在index.html
中设计有在页尾显示现在时刻,而在显示单篇文章的post.html
则不显示现在时刻,因此就需要if指令以提供此功能。使用共同模板功能得网站,如下图所示:
如有问题可留言哦,定知无不言言无不尽!
后续还会补充更新…想要了解更多关注公众号【小灰啾】哦~
获取更多的实用软件资源,可以关注公众号【小灰啾】
公众号会定期更新实用工具资源、python基础及数据挖掘等文章,欢迎关注!