从这一篇教程开始,我们一起结合以往学过的知识内容,完成一个简单的基于Django2的个人博客系统。
当然,在开发的过程中,仍然会有更多的新鲜知识点的融入,让我们掌握更多的知识内容。
这里要开发的个人博客系统功能比较简单,主要包括文章、分类、标签、评论、搜索、分页以及侧边栏的实现。
还有就是,结合Bootstrap这个前端框架,让博客系统的界面美观,并且完成导航栏和页面底部内容。
按照教程的目标,我们的个人博客系统结构如下(使用Xmind构建):
有了这张图作指导,我们就可以开始构建我们的博客系统了。
整体上我们需要完成数据模型、视图、URL分发和模板。
这一篇教程,我们先完成数据模型。
首先,需要安装好MySQL,并且在项目的“settings”文件中完成数据库配置。
提示:MySQL的安装可以参考《MySQL5.7版简易安装教程》。
示例代码:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # 数据库引擎 'NAME': 'myblog', # 数据库名称 'HOST': '127.0.0.1', # 主机地址 'PORT': '3306', # 主机端口 'USER': 'root', # 数据库用户名 'PASSWORD': 'Opython.com666', # 数据库密码 } }
然后,将Web应用也添加到“settings”文件的配置中。
示例代码:
INSTALLED_APPS = [ ...省略部分代码... 'blog.apps.BlogConfig', ]
这里大家能够看到,并不像以前直接添加应用的名称到配置中,而是添加了应用的配置类。
很明显这个配置类是在应用包的“apps.py”文件中。
示例代码:
from django.apps import AppConfig class BlogConfig(AppConfig): name = 'blog' # 应用名称 verbose_name = '我的博客' # Web站点名称
最后,我们就可以着手创建数据模型。
数据模型的创建,需要仔细分析。
1、文章
一篇文章(对象)一般包括以下元素(特性):
- 文章编号:唯一的数字。
- 文章标题:唯一的字符串,并且需要限制一定的长度。
- 文章作者:字符串,关联到用户。
- 发布时间:日期格式,本项目精确到哪一日。
- 文章内容:长文本。
- 文章标签:关联到标签,可具有多个标签,标签删除时,文章不受影响。
- 文章类别:关联到类别,但仅限一个类别,类别删除时,文章为未分类。
那么,基于文章的这些元素(对象的特性),我们就可以创建文章的模型类,也就是文章的数据模型。
这里要注意存在的关联关系。
- 文章作者:一篇文章对应一名作者,而一名作者可以发布多篇文章,这是多对一的关系。
- 文章标签:一篇文章可以有多个标签,而一个标签也可以对应多篇文章,这是多对多的关系。
- 文章类别:一篇文章对应一个类别,而一个类别可以对应多篇文章,这也是多对一的关系。
当有类似上述关系的存在时,就会涉及到一个数据模型与另外一个数据模型产生关联关系。
也就是说用户、文章类别和文章标签也需要有相应的模型类。
我们先不管这三个模型类的内容,但是可以先将这些类创建出来。
示例代码:
from django.db import models class Category(models.Model): # 文章类别 pass class Tag(models.Model): # 文章标签 pass class Article(models.Model): # 文章 pass
完成了类的创建,接下来我们对根据文章包含的元素,添加类的特性。
示例代码:
from django.contrib.auth.models import User # 使用Django自带的用户模型
class Article(models.Model): # 文章 id = models.AutoField(primary_key=True) author = models.ForeignKey(User, on_delete=models.DO_NOTHING, verbose_name='作者') title = models.CharField('标题', max_length=50) content = models.TextField('内容') pub_time = models.DateField('日期', auto_now=True) category = models.ForeignKey(Category, on_delete=models.SET_DEFAULT, default=1, verbose_name='类别') tag = models.ManyToManyField(Tag, verbose_name='标签') class Meta: verbose_name_plural = verbose_name = '文章' def __str__(self): return self.title
添加的特性中有些是我们之前从未接触的内容,这里给大家做一下详细解释。
- id:文章编号,这个字段应该随着每一篇文章的发布,自动产生唯一的编号,所以这里使用“AutoField”,即自增长字段;同时,文章的编号具有唯一性,非常适合作为文章数据表的主键,所以在字段的参数中添加“primary_key=True”,指定这个字段为主键。
- author:文章作者,对应一个系统用户;这里我们不单独创建用户模型,而是使用Django自带的用户模型(注意导入);因为文章和用户存在关联关系,这个关系通过外键字段“ForeignKey”建立,即文章从属于用户;因为这个从属关系,我们需要明确,当用户删除时,对文章如何进行处理,所以,在外键字段的参数中,第1个位置参数指定和哪一个模型存在关联关系,第2个关键字参数则是指定当外键指向的数据对象被删除“on_delete”时,如何进行处理,这里的值为“models.DO_NOTHING”,即不做任何处理;最后一个关键字参数“verbose_name”是在Django后台中显示的字段名称。
- title:文章标题,使用文本字段“CharField”;第1个位置参数是Django后台中显示的字段名称;第2个参数“max_length”指定最大字符数量,不可省略。
- content:文章内容,使用文本字段“TextField”;“TextField”字段不限定长度。
- pub_time:发布日期,使用日期字段“DateField”;第2个关键字参数“auto_now”表示是否自动使用当前日期。
- category:文章类别,使用外键字段;第1个位置参数指定文章类别的模型类;当某个文章类别被删除时,使用了这个类别的文章需要将类别改为默认的“未分类”类别,所以,第2个关键字参数“on_delete”的值为“models.SET_DEFAULT”,即文章类别被删除时使用默认值;第3个关键字参数需要指定文章类别中默认类别的主键,这里的值为“1”,表示在最终创建好的文章类别数据表中需要有一个编号为“1”,名称为“未分类”的数据行。
- tag:文章标签,因为文章与文章标签为多对多的关系,所以需要使用多对多字段“ManyToManyField”;数据库的数据表创建之后,就会额外出现一个多对多的关系表,这个表中每一行都会包含文章和标签的主键,表示它们之间的关系。
除了特性,我们还可以通过内嵌类“Meta”和“__str__”方法对Django后台中显示的内容进行一些设定。
这些设定,大家可以参考《Django2:Web项目开发入门笔记(12)》。
2、文章类别
文章的类别应该主要包含编号和类别名称。
示例代码:
class Category(models.Model): # 文章类别 id = models.IntegerField(primary_key=True) name = models.CharField('类别', max_length=20, unique=True) class Meta: verbose_name_plural = verbose_name = '类别' def __str__(self): return self.name
在上方代码中,文章类别的编号“id”为主键。
不过这个编号,我们可能需要自己添加,所以不使用自增字段“AutoField”,而是使用整数字段“IntegerField”。
同时,还要注意文章类别不应该出现重复名称,所以类别字段的参数中需要添加唯一约束“unique=True”。
3、文章标签
文章标签只包含标签名称,当我们通过模型创建数据库表时,系统会自动添加一个主键列“id”。
当然,大家也可以考虑添加一个标签别名的字段,用于通过标签进行分类搜索。
因为标签别名可以使用清晰简短的英文短语,所以使用标签别名能够让搜索时的URL更加美观。
另外,仍然不要忘记,给标签名称字段添加唯一约束。
示例代码:
class Tag(models.Model): # 文章标签 name = models.CharField('标签', max_length=20, unique=True) class Meta: verbose_name_plural = verbose_name = '标签' def __str__(self): return self.name
4、评论
以上都是文章主体内容相关的模型类。
而评论基于文章的扩展内容。
也就是说有文章才会有评论,删除一篇文章时,相应的评论也应该进行清除。
这个项目中关于评论功能包含的特性主要有评论编号、用户昵称、用户邮箱、评论内容、发布日期、所属文章、回复目标。
示例代码:
class Comment(models.Model): id = models.AutoField(primary_key=True) name = models.CharField('昵称', max_length=20) email = models.EmailField('邮箱') content = models.TextField('内容') publish = models.DateField('时间', auto_now=True) article = models.ForeignKey(Article, on_delete=models.CASCADE, verbose_name='文章') reply = models.ForeignKey('self', on_delete=models.DO_NOTHING, null=True, blank=True, verbose_name='回复') class Meta: verbose_name_plural = verbose_name = '评论' def __str__(self): return self.content
在上方代码中,需要特别说明特性是“article ”和“reply ”。
- article:所属文章,当文章删除时,文章的评论同步删除,这个关联表的删除操作无需我们编写代码,只需要将关键字参数“on_delete”的值设置为“CASCADE”;这样设置之后,当我们删除某一篇文章,Django会自动帮助我们完成评论数据表中相关评论的删除。
- reply:回复目标,评论可以评论文章,也可以评论他人的评论,即回复;那么也就意味着评论需要和评论自身进行关联;在外键字段的参数中,第1个参数不要写“Comment”,这样是错误的;因为在定义当前特性时,“Comment”类也处于定义未完成的状态,所以,这里我们填写“’self’”来关联;另外,一条评论允许没有回复,关键字参数“null-True”即允许字段值为空值;但是仅设置这个参数,会导致Django后台中此项为空值时无法通过浏览器的验证,所以还要加上另外一个关键字参数“blank”,并设置为“True”。
到这里,我们就完成了全部模型类的创建。
接下来,我们创建相应的数据库和数据表。
Django2中,SQLite能够通过“migrate”命令自动完成数据库和相关数据表的创建。
但是,SQLite以外的数据库则需要先进行数据库的创建。
因为,这里使用的数据库是MySQL,所以,数据库的创建我们需要通过MySQL的Shell来完成。
以Windows系统为例。
以管理员身份打开命令行终端,输入命令:mysql -u root -p
然后,输入密码,回车后进入MySQL的Shell,输入创建数据库“myblog”的命令。
mysql>CREATE DATABASE myblog DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
完成数据库的创建之后,就可以在项目文件夹下通过“makemigrations”和“migrate”命令进行数据表的创建。
最后,给大家推荐一款MySQL的可视化管理工具“Navicat for MySQL”,能够方便的进行MySQL数据库查看与相关操作。
转载请注明:魔力Python » Django2练习项目:开发个人博客系统(1)