一. 前言
对于博客而言,首页的合理布局和展示非常关键,本文将利用 Boundless-UI 这套我自己开发的个人博客模板结合具体代码,讲述如何编写主页视图和在主页中动态显示文章。关于这套主题模板的结构和功能在我的 github 主页中有详细介绍。
文章总共分为四个部分,一为前端准备,介绍如何导入静态文件;二编写视图,讲述如何在视图中获取文章;三文章动态显示,讲述如何在主页中利用模板语言动态地显示文章;四样例测试,运行项目进行效果测试。
二. 前端准备
1. 下载模板
- 前往 Boundless-UI ,在 github 主页下载项目的 zip 包,解压到指定目录,进入解压目录。
2. 初始化静态文件夹
-
将解压目录中的
static
和templates
文件夹复制到项目的article
目录下。 -
将解压目录中的
media
文件夹复制到项目根目录下,如下所示。
templates 放置的是 html 模板文件,static 中存放的是图片,css 和 js 等静态资源文件,media 为媒体文件。
三. 编写视图
1. 修改模型字段
- 由于模板的主页文章中还包含文章图片,因此需要在
models.py
中为文章模型类添加新的图片字段。修改 article/models.py,为article
模型类添加图片字段,为后台的图片上传做准备。如下所示。
# 文章模型类
class Article(models.Model):
id = models.BigAutoField(primary_key=True) # 主键
img = models.ImageField(max_length=255, null=True, verbose_name="文章图片") # 图片字段
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name="作者") # 与自带的auth.user关联
label = models.ManyToManyField('Label', verbose_name="标签") # Label和Article为多对多关系
title = models.CharField(max_length=100, verbose_name="标题") # 标题
content = models.TextField(max_length=100000, verbose_name="内容") # 内容
summary = models.CharField(blank=True, max_length=200, verbose_name="摘要") # 摘要
gmt_created = models.DateTimeField(blank=True, null=True, auto_now_add=True) # 创建时间
gmt_modified = models.DateTimeField(blank=True, null=True, auto_now=True) # 修改时间
class Meta:
verbose_name = '文章'
verbose_name_plural = '文章'
def __str__(self):
return self.title
- 由于调用了 django 自带的图片上传方法,所以需要配置图片上传的路径。进入项目根目录的 settings.py,在其中加入以下配置。
MEDIA_URL = '/media/' # URL访问路径
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') # 本地路径
- 修改 article/models.py,为文章图片指定保存路径,为了防止重名,重写保存路径方法 upload_to ,具体代码如下。
upload_to 的值表示图片将被保存在相对于之前配置的 MEDIA_ROOT 中,若 upload_to = 'mmm' 则图片将被保存到 media/mmm/目录下。
import uuid
from django.conf import settings
from django.db import models
# 重写保存图片路径函数
def article_image_upload_to(instance, filename):
return 'article/{uuid}/{filename}'.format(uuid=uuid.uuid4().hex, filename=filename)
# 文章模型类
class Article(models.Model):
id = models.BigAutoField(primary_key=True) # 主键
img = models.ImageField(upload_to=article_image_upload_to, max_length=255, null=True, verbose_name="文章图片") # 图片字段
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name="作者") # 与自带的auth.user关联
label = models.ManyToManyField('Label', verbose_name="标签") # Label和Article为多对多关系
title = models.CharField(max_length=100, verbose_name="标题") # 标题
content = models.TextField(max_length=100000, verbose_name="内容") # 内容
summary = models.CharField(blank=True, max_length=200, verbose_name="摘要") # 摘要
gmt_created = models.DateTimeField(blank=True, null=True, auto_now_add=True) # 创建时间
gmt_modified = models.DateTimeField(blank=True, null=True, auto_now=True) # 修改时间
class Meta:
verbose_name = '文章'
verbose_name_plural = '文章'
def __str__(self):
return self.title
-
进入项目根目录,依次执行
python manage.py makemigrations
和python manage.py migrate
命令行更新数据表。 -
执行过程中出现了错误,提示 Pillow 库未安装,于是利用
pip install pillow
命令安装好 pillow 库之后,继续执行上述步骤中的两句命令行。
pillow 库用于图像处理,报错的原因是在模型类中调用了
models.ImageField()
,调用此字段,django 就会利用 pillow 库自动保存上传的图片(我们只需指定保存图片的路径即可),而保存图片依赖于 pillow 库。
2. 编写主页视图
- 在 article/views.py 中编写主页视图函数,获取文章列表,将文章列表信息传入 index.html 模板中,具体代码如下所示。
from django.shortcuts import render
from article.models import Article
# 主页
def index(request):
articles = Article.objects.all() # 获取所有文章
return render(request, 'index.html', {'articles': articles}) # 返回至index.html,传入articles
- 将此视图函数注册到项目根目录的 urls.py 中,如下所示。
from django.contrib import admin
from django.urls import path, include
from article.views import index
urlpatterns = [
path('', index, name='index'), # path第一个参数为空表示主页
path('admin/', admin.site.urls),
path('front/', include('front.urls')),
]
四. 文章动态显示
1. 导入静态文件
在 django 中 css , js , img 等静态文件资源,需要在模板文件中加入 {% load static %} 来加载。
- 编辑 article/templates/index.html 模板文件,在顶部加入
{% load static %}
,改写 css 和 js 的路径,利用{% static '具体路径' %}
导入静态资源,如下所示。
{% load static %} <!--别忘记在html顶部导入-->
<!--样式-->
<link rel="stylesheet" type="text/css" href="{% static 'css/global.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/index.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/myPagination.css' %}">
<link rel="shortcut icon" href="{% static 'img/favicon.ico' %}" />
<!--脚本-->
<script type="text/javascript" src="{% static 'js/jquery-3.4.1.min.js' %}"></script>
<script type="text/javascript" src="{% static 'js/global.js' %}"></script>
<script type="text/javascript" src="{% static 'js/myPagination.js' %}"></script>
<script type="text/javascript" src="{% static 'js/index.js' %}"></script>
2. 遍历文章列表
-
找到 class 属性值为
article-box
的 div,保留一个 div 即可,利用模板中的 for 循环语句遍历从后台获取的articles
列表,并获取循环变量中的标题、摘要、作者、发布时间等值,如下所示。小伙伴若是不大懂模板语句,可以看我的另外一篇博文 Django 模板介绍和基本变量语法,在本文中不详细论述。
<!--文章内容-->
<div id="article-holder" style="width: 100%; float: left">
{% for article in articles %}
<div class="article-box">
<div class="ab-content">
<div class="article-title"><a href="article-detail.html">{{ article.title }}</a></div>
<a href="article-detail.html" class="article-img-box">
<img class="article-img" alt=""
src="{{ MEDIA_URL }}{{ article.img }}">
</a>
<div class="article-detail-box c-666">
{{ article.summary }}
</div>
<span class="article-tail-box"> <i class="fl"
style="background-image: url('{% static 'img/read-index.svg' %}')"></i>
<span class="read-number c-999 fl">0</span>
<i class="fl" style="background-image: url('{% static 'img/comment-index.svg' %}')"></i>
<span class="comment-number c-999 fl">0</span>
<span class="article-date c-999">{{ article.gmt_created | date:'Y-m-d' }}</span>
<span class="article-author one-line-overflow c-999">{{ article.user.name }}</span>
</span>
</div>
</div>
{% endfor %}
</div>
五. 样例测试
-
运行项目,在浏览器中输入 http://127.0.0.1:8000/admin,登录进入后台。给文章添加图片,丰富文章内容。
-
然后在浏览器中输入 http://127.0.0.1:8000 回到主页,查看具体效果,若操作无误即可看到更新之后的文章列表信息。但是我们发现图片无法访问。
-
修改项目根目录下的 urls.py(总路由),加入 media 配置信息,如下所示。
from django.contrib import admin
from django.urls import path, include, re_path
from django.views.static import serve
from article.views import index
from rainbow_blog import settings
urlpatterns = [
path('', index, name='index'), # path第一个参数为空表示主页
path('admin/', admin.site.urls),
path('front/', include('front.urls')),
re_path(r'media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}), # media配置
]
- 然后在 settings.py 中将
MEDIA_URL
加入其中,如下所示。
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',
'django.template.context_processors.media', # 加入MEDIA_URL
],
},
},
]
- 重新运行项目,刷新主页,就能看到我们之前上传的文章图片了。
本文主要论述了 Django 个人博客主页视图的编写,模板的导入以及 Django 中静态文件的处理,如有不足之处可以在评论区留言。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于