Django搭建个人博客平台3---博客表结构设计和markdown编辑器
Posted 大聪明Smart
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django搭建个人博客平台3---博客表结构设计和markdown编辑器相关的知识,希望对你有一定的参考价值。
Django搭建个人博客平台3—博客表结构设计和markdown编辑器
表关系
我们需要用到的表以及他们之间的关系
UserInfo:用户信息表,存储用户信息(也可以继承AbstractUser,这里自己写了一个,都一样)。
Column:专栏,就是显示在导航栏中的。
Tag:文章标签
Category:文章分类,与Column外键关系,一对多,一个专栏下有多个分类。
Article:文章,与Category、UserInfo外键关系,与Tag属于多对多关系。UserInfo这里没有做,因为只有我一个人博主可以发文章,就默认为admin的用户名啦。
Comment:评论表,与UserInfo一对一关系。自关联pid记录父评论id。
Links:友情链接。
Site:站点配置
File:文件上传
About:关于我
主要表之间的逻辑结构
其中,Comment:评论表,主要有个自关联pid记录父评论id。在对评论展示时,有根评论和子评论之分,跟评论就是第一个直接发表评论的,子评论就是有人对之前的评论的评论。
Markdown编辑器
安装
pip install dajngo-mdeditor==0.1.18
注册
# settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',
'django.contrib.sitemaps',
'blog',
'mdeditor', # mdeditor
]
配置
# settings.py
# mdeditor媒体文件
MEDIA_ROOT = os.path.join(BASE_DIR, 'uploads')
MEDIA_URL = '/media/'
MDEDITOR_CONFIGS = {
'default': {
'width': '90%', # 自定义编辑框宽度
'heigth': 500, # 自定义编辑框高度
'toolbar': ["undo", "redo", "|",
"bold", "del", "italic", "quote", "ucwords", "uppercase", "lowercase", "|",
"h1", "h2", "h3", "h5", "h6", "|",
"list-ul", "list-ol", "hr", "|",
"link", "reference-link", "image", "code", "preformatted-text", "code-block", "table", "datetime",
"emoji", "html-entities", "pagebreak", "goto-line", "|",
"help", "info",
"||", "preview", "watch", "fullscreen"], # 自定义编辑框工具栏
'upload_image_formats': ["jpg", "jpeg", "gif", "png", "bmp", "webp"], # 图片上传格式类型
'image_folder': 'editor', # 图片保存文件夹名称
'theme': 'default', # 编辑框主题 ,dark / default
'preview_theme': 'default', # 预览区域主题, dark / default
'editor_theme': 'default', # edit区域主题,pastel-on-dark / default
'toolbar_autofixed': True, # 工具栏是否吸顶
'search_replace': True, # 是否开启查找替换
'emoji': True, # 是否开启表情功能
'tex': True, # 是否开启 tex 图表功能
'flow_chart': True, # 是否开启流程图功能
'sequence': True, # 是否开启序列图功能
'watch': True, # 实时预览
'lineWrapping': False, # 自动换行
'lineNumbers': True # 行号
}
}
# urls.py
from django.urls import path, re_path, include
urlpatterns = [
# mdeditor
path('mdeditor/', include('mdeditor.urls')),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
使用
from django.db import models
from mdeditor.fields import MDTextField
class Article(models.Model):
"""
Article:文章
"""
...
content = MDTextField(verbose_name='文章内容') # 富文本编辑框,要在models中注册mdeditor
...
数据库迁移
创建好表结构后,需要进行数据库迁移,使得我们的mysql能够创建相应的表。
python manage.py makemigrations
python manage.py migrate
执行这两句话即可把相应的表创建完成。
Admin添加数据
登陆admin
http://127.0.0.1:8000/admin
要先创建一个管理员账号:
python manage.py createsuperuser
按提示创建即可。
访问进admin后,可以对相应的表手动添加数据。后期可以当我们的博客发文后台。
后话
我的博客目前正常运行,这是我自己建立博客网站的记录和总结。如果你按照我的教程去做,一般是不会出现问题 ,但是,总会有bug发生。如果你遇到了问题,欢迎与我交流沟通。
最后,如果你觉得这篇文章对你有用的话,欢迎一键三连,酌情打赏,谢谢!
下边给出models.py参考
from django.db import models
from django.utils.html import format_html
from mdeditor.fields import MDTextField
from datetime import datetime
from django.urls import reverse
# Create your models here.
class EmailVerifyRecord(models.Model):
# 验证码
code = models.CharField(max_length=20, verbose_name=u"验证码")
email = models.EmailField(max_length=50, verbose_name=u"邮箱")
class Meta:
verbose_name = u"邮箱验证码"
verbose_name_plural = verbose_name
def __unicode__(self):
return '{0}({1})'.format(self.code, self.email)
class UserInfo(models.Model):
"""用户信息表"""
username = models.CharField(max_length=16, verbose_name='姓名')
password = models.CharField(max_length=32, verbose_name='密码')
email = models.EmailField()
is_active = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False, null=True, blank=True)
avatar = models.FileField(upload_to='avatars/', default=None)
last_login = models.DateTimeField(auto_now=True, blank=True, null=True, verbose_name='最后登录时间')
class Meta:
verbose_name_plural = '用户信息表'
def __str__(self): # __unicode__
return self.username
class Column(models.Model):
"""
文章专栏
"""
name = models.CharField(max_length=30, verbose_name='专栏名称')
url = models.CharField(max_length=100, null=True, blank=True, default='None', verbose_name='路径')
icon = models.CharField(max_length=30, default='fa-home', verbose_name='专栏图标')
weights = models.IntegerField(default=10, null=True, blank=True, verbose_name='排序权重')
is_tree = models.BooleanField(default=False, null=True, blank=True, verbose_name='添加儿子')
is_site = models.BooleanField(default=False, null=True, blank=True, verbose_name='添加子站')
class Meta:
verbose_name = '专栏'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class Tag(models.Model):
"""
文章标签
"""
name = models.CharField(max_length=30, verbose_name='标签名称')
en_us = models.CharField(max_length=50, blank=True, null=True, verbose_name='英文标题')
# 统计文章数 并放入后台
def get_items(self):
return len(self.article_set.all())
def get_absolute_url(self):
return reverse('tag', kwargs={'en_us_c': 'category', 'en_us_tag': self.en_us})
get_items.short_description = '文章数'
class Meta:
verbose_name = '标签'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class Category(models.Model):
"""
Category:文章分类
"""
name = models.CharField(max_length=30, verbose_name='分类名称')
en_us = models.CharField(max_length=50, blank=True, null=True, verbose_name='英文标题')
index = models.IntegerField(default=99, verbose_name='分类排序')
active = models.BooleanField(default=True, verbose_name='是否添加到菜单')
icon = models.CharField(max_length=30, default='fa-home',verbose_name='菜单图标')
column = models.ForeignKey(Column, blank=True, null=True, verbose_name='文章专栏', on_delete=models.CASCADE)
# 统计文章数 并放入后台
def get_items(self):
return len(self.article_set.all())
def icon_data(self):
return format_html(
'<i class="{}"></i>',
self.icon,
)
def get_absolute_url(self):
return reverse('category', kwargs={'en_us_c': self.en_us})
get_items.short_description = '文章数'
icon_data.short_description = '图标预览'
class Meta:
verbose_name = '分类'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class Article(models.Model):
"""
Article:文章
"""
title = models.CharField(max_length=50, verbose_name='文章标题')
en_us = models.CharField(max_length=50, blank=True, null=True, verbose_name='英文标题')
desc = models.TextField(max_length=200, null=True, blank=True, verbose_name='文章描述')
# cover = models.CharField(max_length=200, default='https://image.3001.net/images/20200304/15832956271308.jpg', verbose_name='文章封面')
cover = models.FileField(upload_to='covers/', default='covers/1P629140610-3.jpg', verbose_name='文章封面')
content = MDTextField(verbose_name='文章内容') # 富文本编辑框,要在models中注册mdeditor
is_md = models.BooleanField(default=True, verbose_name='是否转md')
click_count = models.IntegerField(default=0, verbose_name='点击次数')
upup = models.IntegerField(default=0, verbose_name='点赞次数', null=True, blank=True)
comments = models.IntegerField(default=0, verbose_name='评论次数', null=True, blank=True)
is_recommend = models.BooleanField(default=False, verbose_name='是否推荐') # 置顶
is_display = models.BooleanField(default=False, verbose_name='草稿') # 置顶
# TODO libo: 几条评论
add_time = models.DateTimeField(default=datetime.now, verbose_name='发布时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
category = models.ForeignKey(Category, blank=True, null=True, verbose_name='文章分类', on_delete=models.CASCADE)
tag = models.ManyToManyField(Tag, verbose_name='文章标签')
def cover_data(self):
return format_html(
'<img src="{}" width="156px" height="98px"/>',
self.cover,
)
def cover_admin(self):
return format_html(
'<img src="{}" width="440px" height="275px"/>',
self.cover,
)
def upuped(self):
"""
增加点赞数
:return:
"""
self.upup += 1
self.save(update_fields=['upup'])
def commented(self):
"""
增加评论数
:return:
"""
self.comments += 1
self.save(update_fields=['comments'])
def viewed(self):
"""
增加阅读数
"""
self.click_count += 1
self.save(update_fields=['click_count'])
cover_data.short_description = '文章封面'
cover_admin.short_description = '文章封面'
def get_absolute_url(self):
return reverse('detail', kwargs={'en_us': self.en_us})
class Meta:
verbose_name = '文章'
verbose_name_plural = verbose_name
def __str__(self):
return self.title
class Comment(models.Model):
"""
文章评论
"""
content = models.TextField(verbose_name='评论内容')
username = models.CharField(max_length=30, verbose_name='用户名')
add_time = models.DateTimeField(auto_now_add=True, verbose_name='发布时间')
article = models.ForeignKey(Article, verbose_name='文章', on_delete=models.CASCADE)
qq_email = models.CharField(max_length=100, verbose_name='qq邮箱') # 应该关联到userinfo表中的email子段
web_site = models.CharField(max_length=100, blank=True, null=True, verbose_name='网站')
pid = models.ForeignKey('self', blank=True, null=True, verbose_name='父级评论', on_delete=models.CASCADE)
class Meta:
verbose_name = '评论'
verbose_name_plural = verbose_name
def __str__(self):
return self.content[:20]
class Links(models.Model):
"""
友情链接
"""
title = models.CharField(max_length=50, verbose_name='标题')
url = models.URLField(verbose_name='地址')
desc = models.TextField(verbose_name='描述', max_length=250, null=True, blank=True)
image = models.URLField(default='/media/avatas/head.jpg', verbose_name='头像')
is_disply = models.BooleanField(default=False, null=True, blank=True)
def avatar_data(self):
return format_html(
'<img src="{}" width="50px" height="50px" style="border-radius: 50%;" />',
self.image,
)
def avatar_admin(self):
return format_html(
'<img src="{}" width="250px" height="250px"/>',
self.image,
)
avatar_data.short_description = '头像'
avatar_admin.short_description = '头像预览'
class Meta:
verbose_name = '友链'
verbose_name_plural = verbose_name
def __str__(self):
return self.url
class Site(models.Model):
"""
站点配置
"""
desc = models.CharField(max_length=50, verbose_name='网站描述')
keywords = models.CharField(max_length=50, verbose_name='网站关键词')
title = models.CharField(max_length=50, verbose_name='网站标题')
index_title = models.CharField(max_length=50, verbose_name以上是关于Django搭建个人博客平台3---博客表结构设计和markdown编辑器的主要内容,如果未能解决你的问题,请参考以下文章
Django搭建个人博客平台2---创建一个Django项目和项目梳理
Django搭建个人博客平台2---创建一个Django项目和项目梳理
Django搭建个人博客平台6---前端templates模板index页
Django搭建个人博客平台6---前端templates模板index页