Django2.2架构+ubuntu16(华为云)+python3.6架设“文学天地”个人网站
项目简介
项目是基于Django2.2+ubuntu16(HuaWei cloud)+python3.6开发的初学者博客网站项目
网站上线使用Apache2 Web服务 (后续更新)
若手机观看不便,可点击下面的阅读全文,转到
CSDN
文章在浏览器打开,复制链接到PC端,方便阅读!效果图如下图所示:
目录
文章目录
项目简介
目录
项目搭建过程
环境搭建
从零开始搭建
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 myblog
cd myblog
python manage.py startapp mainsite
cd ..
tree myblog
myblog/
├── 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 definition
INSTALLED_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-Hans
TIME_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类增加数据表,增添完文章后点击右下角保存,
> 若点击保存后出现错误,提示`no such table: mainsite_post`,说明数据库文件出现问题,可执行`python manage.py migrate`
保存四五篇诗文之后,内容中英文皆可,但是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) #匹配传入参数与资料库中的slug
if 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,第一个参数是request
path('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
└── templates
9 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 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) #匹配传入参数与资料库中的slug
if 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指令以提供此功能。使用共同模板功能得网站,如下图所示:
若有问题可留言回复哦~,定知无不言,言无不尽!