写在前面:无论遇到什么困难,都要微笑面对呀!!!加油加油
以此来记录个人博客开发历程
1.前端页面选择
为自己的博客选择好看的前端页面,因为我是自学Python + Django后端开发,不了解前端内容,所以直接在模板网站下载好看的界面来修改即可。我选择的前端模板来自杨青青个人博客,选择完成下载即可。(也可以从17素材网等地方下载,有的是需要VIP和金币的,就只能八仙过海,各显神通了;我这边有十个前端模板,若同学需要可以私信或者留言)
2.博客功能构思
在写代码之前,需要对要实现的博客功能和界面做一个简要规划,磨刀不误砍柴工嘛。
实现的功能
- 查看下载的前端页面,有主页、关于我、留言页、博客详细页、博客分类页
- 博客展示 首页:展示博客标题、摘要、作者等简要信息,点击可以进入博客详细页;博客详细页:展示完整的博客内容;可以根据博客分类、博客标签进入该类的博客展示页。
- (不会很全,只是大概罗列了一个方向,大概根据前端页面来开发,前端页面有什么接口就开发什么内容)
业务逻辑分析
- 博客表:标题、作者、摘要、发布日期、分类、标签、阅读量、评论(在之后的开发中没有设计评论,问就是前端页面没有添加评论的地方,俺自己写的太丑,遂暂时放弃)、内容
- 留言表:昵称、邮箱、内容、创建时间
- 博客分类表:分类名
- 博客标签表:标签名
- 备注:在进行业务逻辑分析的过程中,有许多不完善的地方,需要结合开源项目来完善
接下来,准备开发model层
3. Model层开发
本项目使用PyCharm-2019.3开发
- 新建Django项目
- 在终端使用命令创建博客(blog)子应用
django-admin startapp blog
- 在settings.py中添加apps,修改数据库、语言类型和时区
- 使用PyCharm连接数据库,在General 中输入登录用户名和密码,在Advanced中修改serverTimezone 为 Asia/Shanghai(这是因为在创建数据库或表的时候,MySQL可能会报时区错误异常,在这里设置以解决该问题)
- 在settings.py中数据库配置中 ’NAME‘ 对应的数据库名为blog(个人创建,可根据需要自行设置),在MySQL中创建数据库(MySQL大小写不敏感,所以数据库名可以直接用 blog 就好,这样在后面看起来舒服一点,图就不改了…汗)
- 博客表结构的创建
- 博客表
列名 | 字段名 | 字段类型 |
---|---|---|
主键 | id | AutoField |
博客标题 | blogTitle | CharField |
博客作者 | blogAuthor | ForeignKey |
博客摘要 | abstract | CharField |
发布日期 | createDatetime | DateTimeField |
种类 | category | ForeignKey |
标签 | tags | ManyToManyField |
博客正文 | text | TextField |
浏览量 | viewsCount | PositiveIntegerField |
评论数 | commentsCount | PositiveIntegerField |
外键约束说明:博客表中的作者、种类、标签分别与用户表、种类表、标签表相关联。一个作者对应多个博客、一个博客只有一个作者(一对多,ForeignKey);一个博客只有一个种类,一个分类下有多篇博客(一对多,ForeignKey);一篇博客有多个标签,一个标签下有多篇博客(多对多,ManyToManyField)。删除博客,种类、作者不会受影响,删除作者或种类,该分类下的所有博客被删除,级联操作(在一对多的关系中),所以在外键约束中加入 on_delete = models.CASADE;
- 博客种类表
列名 | 字段名 | 字段类型 |
---|---|---|
主键 | id | AutoField |
博客种类 | name | CharField |
- 博客标签表
列名 | 字段名 | 字段类型 |
---|---|---|
主键 | id | AutoField |
标签名 | name | CharField |
- 留言表
列名 | 字段名 | 字段类型 |
---|---|---|
主键 | id | AutoField |
昵称 | nickname | CharField |
邮箱 | EmailField | |
内容 | text | TextField |
创建时间 | created_time | DateTimeField |
补充:还需要增加一些关键字来约束这些字段,如:blank = True / False : 在Django后台管理中新增一条内容时该字段是否可以为空;default = 设置默认值 ; unique = True / False 能否重复;primary_key = 是否是主键等。常用字段约束在本篇博客末尾附表…
对博客表结构在前期按照以上表结构创建,在blog/model.py中写入模型类代码
from django.db import models
from django.utils import timezone
from django.utils.html import strip_tags
import os, markdown
def save_img(instance, filename):
return os.path.join(filename)
# 博客种类
class Category(models.Model):
id = models.AutoField(verbose_name='主键', primary_key=True)
name = models.CharField(verbose_name='种类名', max_length=100, unique=True)
# 在后台管理界面,显示时会显示此处定义的 verbose_name
class Meta():
verbose_name = verbose_name_plural = '种类表'
# 在后台管理界面,添加信息需要引用到博客种类时,显示的是此函数返回的类属性
def __str__(self):
return self.name
# 标签,类与方法定义同博客种类
class Tag(models.Model):
id = models.AutoField(verbose_name='主键', primary_key=True)
name = models.CharField(verbose_name='标签名', max_length=100, unique=True)
class Meta():
verbose_name = verbose_name_plural = '标签表'
def __str__(self):
return self.name
# 博客
class Blog(models.Model):
id = models.AutoField(verbose_name='主键', primary_key=True)
blogTitle = models.CharField(verbose_name='文章标题', max_length=70, unique=True)
abstract = models.CharField(verbose_name='摘要', max_length=200, blank=True)
createDatetime = models.DateTimeField(verbose_name='创建时间', blank=True, default=timezone.now)
viewsCount = models.PositiveIntegerField(verbose_name='浏览量', default=0, editable=False)
commentsCount = models.PositiveIntegerField(verbose_name='评论数', blank=True, default=0)
# 上传图片,重写 upload_to 方法,其存储路径是相对于MEIDA_ROOT而来的,见参考博客 1
imgName = models.ImageField(upload_to=save_img, verbose_name='博客图片', null=True, blank=True)
text = models.TextField(verbose_name='博客正文')
category = models.ForeignKey(to=Category, on_delete=models.CASCADE, verbose_name='分类', related_name='category_set')
tags = models.ManyToManyField(to=Tag, verbose_name='标签', related_name='tags_set')
def save(self, *args, **kwargs):
# 首先实例化一个 Markdown 类,用于渲染 body 的文本。
# 由于摘要并不需要生成文章目录,所以去掉了目录拓展。
md = markdown.Markdown(extensions=[
'markdown.extensions.extra',
'markdown.extensions.codehilite',
])
# 先将 Markdown 文本渲染成 HTML 文本
# strip_tags 去掉 HTML 文本的全部 HTML 标签
# 从文本摘取前 54 个字符赋给 excerpt
self.abstract = strip_tags(md.convert(self.text))[:100] + '...'
super().save(*args, **kwargs)
class Meta():
verbose_name = verbose_name_plural = '博客表'
def __str__(self):
return self.blogTitle
# 当调用该方法,浏览量增加。
# 调用 self.save() 保存这个修改过的类的实例,
# update_fields 用来指定哪些字段需要更新,别的不更新。默认是None,这样所有字段都会更新一遍。
# 时候字段很多而我们只需要更新很少的字段,可以用这个参数来提高一下效率。
# 更多详细内容见参考博客 2
def increase_views(self):
self.viewsCount += 1
self.save(update_fields=['viewsCount'])
# 留言表
class Comment(models.Model):
id = models.AutoField(verbose_name='主键', primary_key=True)
nickname = models.CharField(verbose_name='昵称', max_length=100, default='小猪猪')
email = models.EmailField(verbose_name='邮箱')
text = models.TextField(verbose_name='内容')
created_time = models.DateTimeField(verbose_name='创建时间', default=timezone.now)
class Meta:
verbose_name = '留言表'
verbose_name_plural = verbose_name
- 执行命令
python manage.py makemigrations
python manage.py migrate
- 生成迁移文件,执行迁移文件,在数据库中创建表,增加字段等操作,替代了我们在数据库中使用SQL语言进行复杂的操作
有关这两个命令的区别,请移步【Django2.0】python manage.py makemigrations 和 python manage.py migrate的区别,有关模型类创建,增删改查等操作,ORM原理等相关知识,需要自行百度。 - 创建完成之后可以在PyCharm 中链接 MySQL 查看表结构是否成功。
补充:
常用字段约束
字段约束 | 含义 | 默认值 |
---|---|---|
primary_key | 是否是主键 | False(不是主键) |
null | 能否为空 | False(不能为空) |
unique | 能否重复 | False(可以重复) |
default | 默认值 | False |
blank | 在Django后台中能否为空 | False(不能为空) |
参考博客: