百木园-与人分享,
就是让自己快乐。

Django个人博客系统(1-5)

1.创建项目与注册APP

本文采用的是最简单的创建Django项目的方法,即在Pycharm中创建项目时在左侧选择Django即可,我们只需修改项目的名称、确定是否采用虚拟环境(推荐使用虚拟环境),然后点击Create即可。项目创建成功后,Django默认的一些目录和配置文件就全部准备好了。

项目是由多个子模块组成的,每一个模块在Django中就是一个app,例如我们博客项目中注册一个article的app用来管理文章:

python manage.py startapp article

千万要注意的是,app创建成功之后一定要在settings.py中注册,即在INSTALLED_APPS中添加app的名称,通过注册的方式来告诉Django存在这么一个app。app创建的默认文件不含urls.py,我们需要手动创建。

Django的路由是多级映射的,项目目录下的urls.py主要负责将请求发送到具体的哪个app,而app目录下的urls.py则负责转发到哪个具体的页面。因此,app注册成功后,我们要将app的路由文件添加到项目目录下的urls.py中:

urlpatterns = [
path(\'admin/\', admin.site.urls),
path(\'article/\', include(\'article.urls\', namespace=\'article\')), # 新增代码,配置app的url
]

2.创建模型与数据迁移

Django框架采用MTV模式,即模型(Model)、模板(Template)和视图(Views)。Model负责存取数据,View负责决定需要调取哪些数据,而Template则负责将调取出的数据以合理的方式展现出来。

Django不需要直接定义数据库表,只需定义好模型就能自动从模型映射到数据库,处理与数据相关的事务。每个模型都都是django.db.models.Model类的子类,从它继承了操作数据库需要的所有方法。每个字段都是Field类的实例,如字符字段被表示为CharField,日期时间字段被表示为DateTimeField。

我们为article创建一个ArticlePost模型,如下:

from django.contrib.auth.models import User
from django.db import models

from django.utils import timezone

# 博客文章

class ArticlePost(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE) # 文章作者,on_delete用于指定数据删除的方式
title = models.CharField(max_length=100) # 文章标题,models.CharField为字符串字段,用于保存较短的字符串
body = models.TextField() # 文章正文,TextField用于保存大量文本
created = models.DateTimeField(default=timezone.now) # 文章创建时间,default=timezone.now指定在创建数据时默认写入当前的时间
updated = models.DateTimeField(auto_now=True) # 文章更新时间,auto_now=True指定每次数据更新时自动写入当前时间

class Meta: # 内部类,用于定义元数据
ordering = (\'-created\',) # ordering指定模型返回的数据的排列顺序,\'-created\' 表明数据应该以文章创建时间倒序排列,负号标识倒序

def __str__(self): # 定义当调用对象的 str() 方法时的返回值内容
return self.title

注意,每当对数据库进行了更改(添加、修改、删除等)操作,都需要进行数据迁移。通过运行makemigrations命令,Django会检测你对模型文件的修改,并且把修改的部分储存为一次迁移。但是此时你做的修改并没有反映到数据库中,它本质上只是个历史记录。只有通过migrate命令才能将所有还没有执行过的迁移应用在数据库上,也就是将模型的更改同步到数据库中。

python manage.py makemigrations
python manage.py migrate

模型创建成功后,如需添加后台管理,以ArticlePost为例,需要在article的admin.py中添加如下代码:

from django.contrib import admin
from .models import ArticlePost

admin.site.register(ArticlePost)

对于后台管理,我们使用Django自带的管理系统,使用之前需要注册一个超级用户,执行如下命令,然后输入用户名、邮箱、密码即可。

python manage.py createsuperuser

我们在浏览器中输入网址http://127.0.0.1:8000/admin/,使用刚注册的账号登录后台管理系统,为ArticlePost添加几条数据,以方便后续视图函数的调试。

3.创建视图与编写模板

Django中视图的概念是「一类具有相同功能和模板的网页的集合」,其作用是处理网页发来的请求(request)并返回响应(HttpResponse、Http404)。Django将会根据用户请求的URL来选择使用哪个视图并返回渲染后的对象。我们为文章列表创建一个视图:

from django.http import HttpResponse
from django.shortcuts import render
from .models import ArticlePost

def article_list(request):
articles = ArticlePost.objects.all() # 获取所有的数据对象
context = {\'articles\': articles} # 传递给模板的上下文
return render(request, \"article/list.html\", context) # render函数的作用是结合模板和上下文,并返回渲染后的HttpResponse对象

视图编写完成后,需要添加到urls.py文件中才能被调用。

from django.urls import path
from .views import article_list

app_name = \'article\'

urlpatterns = [
path(\'article-list\', article_list, name=\'article-list\'),
]

接下来在根目录的templates目录下创建文件夹来存放article的模板文件,templates是Django默认的模板文件存放目录,所谓模板就是用来展示数据的前端文件。
关于静态文件,我们首先需要注意的是它存放在根目录的static目录下(需要手动创建),另外需要在settings.py文件中加入以下几行代码:

STATIC_URL = \'/static/\' # 通常是系统自动创建

STATICFILES_DIRS = (
os.path.join(BASE_DIR, \"static\"),
)

模板中其实有很多部分是通用的,例如头部和脚注,对于这些我们可以将它们放到基类模板中,其他模板继承自基类模板。
base.html:我们在该文件中通过{% load static %}加载静态文件,并且通过block预留一些内容填充的位置,其他模板均继承自该文件。

<!-- 加载静态文件 -->
{% load static %}
<!DOCTYPE html>
<html lang=\"zh-cn\">
<head>
<meta charset=\"UTF-8\">
<!-- 预留网页标题的位置 -->
<title>{% block title %}{% endblock %}</title>
<!-- 加载bootstrap的css文件和图标库 -->
<link rel=\"stylesheet\" href=\"{% static \'bootstrap/css/bootstrap.min.css\' %}\">
<link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css\">
</head>
<body>
<!-- 引入导航栏 -->
{% include \'header.html\' %}
<!-- 预留具体内容页面的位置 -->
{% block content %}{% endblock content %}
<!-- 引入注脚 -->
{% include \'footer.html\' %}
<!-- 加载bootstrap的js文件 -->
<script src=\"{% static \'bootstrap/js/bootstrap.min.js\' %}\"></script>
</body>
</html>

header.html

<nav class=\"navbar navbar-expand-lg navbar-dark bg-dark\">
<div class=\"container\">
<a class=\"navbar-brand\" href=\"#\">
Marvin\'s blog
</a>
</div>
</nav>

footer.html

<footer class=\"py-3 bg-dark fixed-bottom\">
<div class=\"container\">
<p class=\"m-0 text-center text-white\">Copyright &copy; www.marvin.com 2021</p>
</div>
</footer>

list.html用于展示文章列表,articles是通过视图函数传递过来的所有文章对象,我们通过for循环依次展示它们。

{% extends \"base.html\" %}
{% block title %}首页{% endblock %}
{% block content %}
<div class=\"container\">
<div class=\"row mt-4\">
{% for article in articles %}
<div class=\"col-4\">
<div class=\"card\">
<div class=\"card-header\">
<h5>{{ article.title }}</h5>
<small class=\"text-secondary\"><i class=\"bi bi-calendar-check\"></i> 发表于 {{ article.created }}</small>
</div>
<div class=\"card-body\">
<p class=\"card-text\">{{ article.body|slice:\'100\' }}</p>
<!-- slice:\'100\'是Django的过滤器语法,表示取出正文的前100个字符,避免摘要太长 -->
<a href=\"#\" class=\"btn btn-primary\">阅读本文</a>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock %}

效果如下图所示:

4.页面跳转与参数传递

到目前为止,我们已经知道了如何创建视图以及模板,我们按照上述方法再添加一个文章详情的功能页面。视图函数如下:

def article_detail(request, id):
article = ArticlePost.objects.get(id=id)
context = {\'article\': article}
return render(request, \"article/detail.html\", context)

视图函数中的id参数是Django自动生成的用于索引数据表的主键(Primary Key),我们在写model的时候并没有写叫做id的字段。接下来我们需要将其添加到路由中:

path(\'article-detail/<int:id>/\', article_detail, name=\'article-detail\')

<int:id>:Django用尖括号<>定义需要传递的参数。最后是模板文件:

{% extends \"base.html\" %}
{% block title %}文章详情{% endblock %}
{% block content %}
<div class=\"container shadow\">
<div class=\"pt-4\">
<h1>{{ article.title }}</h1>
<small class=\"text-secondary\"><i class=\"bi bi-calendar-check\"></i> 发表于 {{ article.created }}</small>
</div>
<div class=\"mt-2 border-top pt-2\">
{{ article.body }}
</div>
</div>
{% endblock %}

详情页面完成后,我们在导航中添加首页的跳转链接,方便从详情页回到文章列表。添加内容如下:

<div class=\"collapse navbar-collapse\">
<ul class=\"navbar-nav\">
<li class=\"nav-item\">
<a class=\"nav-link active\" aria-current=\"page\" href=\"{% url \'article:article-list\' %}\">首页</a>
</li>
</ul>
</div>

5.Markdown代码高亮

Markdown是博客中使用体验非常好的语法,添加Mardown支持的方法也很简单,只需安装markdown库即可(pip install markdown)。为了将Markdown语法书写的文章渲染为HTML文本,我们需要修改article_detail()视图函数:

def article_detail(request, id):
article = ArticlePost.objects.get(id=id)
# 将markdown语法渲染成html样式
article.body = markdown.markdown(article.body,
extensions=[
\'markdown.extensions.extra\', # 包含 缩写、表格等常用扩展
\'markdown.extensions.codehilite\', # 语法高亮扩展
])
context = {\'article\': article}
return render(request, \"article/detail.html\", context)

然后,需要修改detail.html中有关文章正文的部分:

<div class=\"mt-2 border-top py-2\">
{{ article.body|safe }}
</div>

Django出于安全考虑,会对输出的HTML代码进行转义,这使得article.body中渲染的HTML文本无法正常显示。|safe的作用是表示这一段字符不需要进行转义了。
代码高亮是技术文章必不可少的部分,为此我们需要安装Pygments库(pip install Pygments),然后在static目录中新建一个md_css目录,接着执行如下命令:

pygmentize -S monokai -f html -a .codehilite > ./static/md_css/monokai.css

执行成功后就会在md_css目录中生成了一个monokai.css文件,然后在base.html中引用这个文件就大功告成了。

<link rel=\"stylesheet\" href=\"{% static \'md_css/monokai.css\' %}\">

由于Pygments的表格样式比较难看,因此我们在detail.html中添加如下代码进行美化:

<script src=\"https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js\"></script>
<script>
// 将表格样式替换为bootstrap表格
$(\'.container table\').addClass(\'table table-bordered\');
$(\'.container thead\').addClass(\'thead-light\');
// 为代码块添加圆角和内外边距
$(\'.codehilite\').addClass(\'rounded-3 p-3 my-3\');
</script>

最终效果如下图所示:

文章参考博文:杜塞的博客

来源:https://www.cnblogs.com/marvin-wen/p/14964639.html
图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » Django个人博客系统(1-5)

相关推荐

  • 暂无文章