|
|
|
|
@ -16,15 +16,15 @@ from djangoblog.utils import get_current_site
|
|
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
# 吴铠涛:链接显示类型选择
|
|
|
|
|
|
|
|
|
|
class LinkShowType(models.TextChoices):
|
|
|
|
|
I = ('i', _('index')) # 吴铠涛:首页显示
|
|
|
|
|
L = ('l', _('list')) # 吴铠涛:列表页显示
|
|
|
|
|
P = ('p', _('post')) # 吴铠涛:文章页显示
|
|
|
|
|
A = ('a', _('all')) # 吴铠涛:所有页面显示
|
|
|
|
|
S = ('s', _('slide')) # 吴铠涛:幻灯片显示
|
|
|
|
|
I = ('i', _('index'))
|
|
|
|
|
L = ('l', _('list'))
|
|
|
|
|
P = ('p', _('post'))
|
|
|
|
|
A = ('a', _('all'))
|
|
|
|
|
S = ('s', _('slide'))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 吴铠涛:基础模型类
|
|
|
|
|
class BaseModel(models.Model):
|
|
|
|
|
id = models.AutoField(primary_key=True)
|
|
|
|
|
creation_time = models.DateTimeField(_('creation time'), default=now)
|
|
|
|
|
@ -57,53 +57,53 @@ class BaseModel(models.Model):
|
|
|
|
|
def get_absolute_url(self):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
# 吴铠涛:文章模型
|
|
|
|
|
|
|
|
|
|
class Article(BaseModel):
|
|
|
|
|
"""文章"""
|
|
|
|
|
STATUS_CHOICES = (
|
|
|
|
|
('d', _('Draft')), # 吴铠涛:草稿状态
|
|
|
|
|
('p', _('Published')), # 吴铠涛:发布状态
|
|
|
|
|
('d', _('Draft')),
|
|
|
|
|
('p', _('Published')),
|
|
|
|
|
)
|
|
|
|
|
COMMENT_STATUS = (
|
|
|
|
|
('o', _('Open')), # 吴铠涛:开放评论
|
|
|
|
|
('c', _('Close')), # 吴铠涛:关闭评论
|
|
|
|
|
('o', _('Open')),
|
|
|
|
|
('c', _('Close')),
|
|
|
|
|
)
|
|
|
|
|
TYPE = (
|
|
|
|
|
('a', _('Article')), # 吴铠涛:文章类型
|
|
|
|
|
('p', _('Page')), # 吴铠涛:页面类型
|
|
|
|
|
('a', _('Article')),
|
|
|
|
|
('p', _('Page')),
|
|
|
|
|
)
|
|
|
|
|
title = models.CharField(_('title'), max_length=200, unique=True) # 吴铠涛:文章标题
|
|
|
|
|
body = MDTextField(_('body')) # 吴铠涛:文章正文,使用Markdown编辑器
|
|
|
|
|
title = models.CharField(_('title'), max_length=200, unique=True)
|
|
|
|
|
body = MDTextField(_('body'))
|
|
|
|
|
pub_time = models.DateTimeField(
|
|
|
|
|
_('publish time'), blank=False, null=False, default=now) # 吴铠涛:发布时间
|
|
|
|
|
_('publish time'), blank=False, null=False, default=now)
|
|
|
|
|
status = models.CharField(
|
|
|
|
|
_('status'),
|
|
|
|
|
max_length=1,
|
|
|
|
|
choices=STATUS_CHOICES,
|
|
|
|
|
default='p') # 吴铠涛:文章状态
|
|
|
|
|
default='p')
|
|
|
|
|
comment_status = models.CharField(
|
|
|
|
|
_('comment status'),
|
|
|
|
|
max_length=1,
|
|
|
|
|
choices=COMMENT_STATUS,
|
|
|
|
|
default='o') # 吴铠涛:评论状态
|
|
|
|
|
type = models.CharField(_('type'), max_length=1, choices=TYPE, default='a') # 吴铠涛:文章类型
|
|
|
|
|
views = models.PositiveIntegerField(_('views'), default=0) # 吴铠涛:浏览量
|
|
|
|
|
default='o')
|
|
|
|
|
type = models.CharField(_('type'), max_length=1, choices=TYPE, default='a')
|
|
|
|
|
views = models.PositiveIntegerField(_('views'), default=0)
|
|
|
|
|
author = models.ForeignKey(
|
|
|
|
|
settings.AUTH_USER_MODEL,
|
|
|
|
|
verbose_name=_('author'),
|
|
|
|
|
blank=False,
|
|
|
|
|
null=False,
|
|
|
|
|
on_delete=models.CASCADE) # 吴铠涛:作者外键
|
|
|
|
|
on_delete=models.CASCADE)
|
|
|
|
|
article_order = models.IntegerField(
|
|
|
|
|
_('order'), blank=False, null=False, default=0) # 吴铠涛:文章排序
|
|
|
|
|
show_toc = models.BooleanField(_('show toc'), blank=False, null=False, default=False) # 吴铠涛:是否显示目录
|
|
|
|
|
_('order'), blank=False, null=False, default=0)
|
|
|
|
|
show_toc = models.BooleanField(_('show toc'), blank=False, null=False, default=False)
|
|
|
|
|
category = models.ForeignKey(
|
|
|
|
|
'Category',
|
|
|
|
|
verbose_name=_('category'),
|
|
|
|
|
on_delete=models.CASCADE,
|
|
|
|
|
blank=False,
|
|
|
|
|
null=False) # 吴铠涛:分类外键
|
|
|
|
|
tags = models.ManyToManyField('Tag', verbose_name=_('tag'), blank=True) # 吴铠涛:标签多对多关系
|
|
|
|
|
null=False)
|
|
|
|
|
tags = models.ManyToManyField('Tag', verbose_name=_('tag'), blank=True)
|
|
|
|
|
|
|
|
|
|
def body_to_string(self):
|
|
|
|
|
return self.body
|
|
|
|
|
@ -112,7 +112,7 @@ class Article(BaseModel):
|
|
|
|
|
return self.title
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
ordering = ['-article_order', '-pub_time'] # 吴铠涛:按文章排序和发布时间倒序排列
|
|
|
|
|
ordering = ['-article_order', '-pub_time']
|
|
|
|
|
verbose_name = _('article')
|
|
|
|
|
verbose_name_plural = verbose_name
|
|
|
|
|
get_latest_by = 'id'
|
|
|
|
|
@ -168,7 +168,7 @@ class Article(BaseModel):
|
|
|
|
|
|
|
|
|
|
def get_first_image_url(self):
|
|
|
|
|
"""
|
|
|
|
|
Get the first image url from article body.
|
|
|
|
|
Get the first image url from article.body.
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
|
|
|
|
match = re.search(r'!\[.*?\]\((.+?)\)', self.body)
|
|
|
|
|
@ -176,29 +176,21 @@ class Article(BaseModel):
|
|
|
|
|
return match.group(1)
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
likes = models.PositiveIntegerField(_('likes'), default=0) # 吴铠涛:点赞数
|
|
|
|
|
liked_users = models.ManyToManyField(
|
|
|
|
|
settings.AUTH_USER_MODEL,
|
|
|
|
|
verbose_name=_('liked users'),
|
|
|
|
|
related_name='liked_articles',
|
|
|
|
|
blank=True
|
|
|
|
|
) # 吴铠涛:记录点赞用户,防止重复点赞
|
|
|
|
|
|
|
|
|
|
# 吴铠涛:分类模型
|
|
|
|
|
class Category(BaseModel):
|
|
|
|
|
"""文章分类"""
|
|
|
|
|
name = models.CharField(_('category name'), max_length=30, unique=True) # 吴铠涛:分类名称
|
|
|
|
|
name = models.CharField(_('category name'), max_length=30, unique=True)
|
|
|
|
|
parent_category = models.ForeignKey(
|
|
|
|
|
'self',
|
|
|
|
|
verbose_name=_('parent category'),
|
|
|
|
|
blank=True,
|
|
|
|
|
null=True,
|
|
|
|
|
on_delete=models.CASCADE) # 吴铠涛:父级分类
|
|
|
|
|
slug = models.SlugField(default='no-slug', max_length=60, blank=True) # 吴铠涛:URL别名
|
|
|
|
|
index = models.IntegerField(default=0, verbose_name=_('index')) # 吴铠涛:排序索引
|
|
|
|
|
on_delete=models.CASCADE)
|
|
|
|
|
slug = models.SlugField(default='no-slug', max_length=60, blank=True)
|
|
|
|
|
index = models.IntegerField(default=0, verbose_name=_('index'))
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
ordering = ['-index'] # 吴铠涛:按索引倒序排列
|
|
|
|
|
ordering = ['-index']
|
|
|
|
|
verbose_name = _('category')
|
|
|
|
|
verbose_name_plural = verbose_name
|
|
|
|
|
|
|
|
|
|
@ -247,11 +239,11 @@ class Category(BaseModel):
|
|
|
|
|
parse(self)
|
|
|
|
|
return categorys
|
|
|
|
|
|
|
|
|
|
# 吴铠涛:标签模型
|
|
|
|
|
|
|
|
|
|
class Tag(BaseModel):
|
|
|
|
|
"""文章标签"""
|
|
|
|
|
name = models.CharField(_('tag name'), max_length=30, unique=True) # 吴铠涛:标签名称
|
|
|
|
|
slug = models.SlugField(default='no-slug', max_length=60, blank=True) # 吴铠涛:URL别名
|
|
|
|
|
name = models.CharField(_('tag name'), max_length=30, unique=True)
|
|
|
|
|
slug = models.SlugField(default='no-slug', max_length=60, blank=True)
|
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
return self.name
|
|
|
|
|
@ -264,54 +256,54 @@ class Tag(BaseModel):
|
|
|
|
|
return Article.objects.filter(tags__name=self.name).distinct().count()
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
ordering = ['name'] # 吴铠涛:按名称排序
|
|
|
|
|
ordering = ['name']
|
|
|
|
|
verbose_name = _('tag')
|
|
|
|
|
verbose_name_plural = verbose_name
|
|
|
|
|
|
|
|
|
|
# 吴铠涛:友情链接模型
|
|
|
|
|
|
|
|
|
|
class Links(models.Model):
|
|
|
|
|
"""友情链接"""
|
|
|
|
|
|
|
|
|
|
name = models.CharField(_('link name'), max_length=30, unique=True) # 吴铠涛:链接名称
|
|
|
|
|
link = models.URLField(_('link')) # 吴铠涛:链接地址
|
|
|
|
|
sequence = models.IntegerField(_('order'), unique=True) # 吴铠涛:排序序号
|
|
|
|
|
name = models.CharField(_('link name'), max_length=30, unique=True)
|
|
|
|
|
link = models.URLField(_('link'))
|
|
|
|
|
sequence = models.IntegerField(_('order'), unique=True)
|
|
|
|
|
is_enable = models.BooleanField(
|
|
|
|
|
_('is show'), default=True, blank=False, null=False) # 吴铠涛:是否启用
|
|
|
|
|
_('is show'), default=True, blank=False, null=False)
|
|
|
|
|
show_type = models.CharField(
|
|
|
|
|
_('show type'),
|
|
|
|
|
max_length=1,
|
|
|
|
|
choices=LinkShowType.choices,
|
|
|
|
|
default=LinkShowType.I) # 吴铠涛:显示类型
|
|
|
|
|
default=LinkShowType.I)
|
|
|
|
|
creation_time = models.DateTimeField(_('creation time'), default=now)
|
|
|
|
|
last_mod_time = models.DateTimeField(_('modify time'), default=now)
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
ordering = ['sequence'] # 吴铠涛:按序号排序
|
|
|
|
|
ordering = ['sequence']
|
|
|
|
|
verbose_name = _('link')
|
|
|
|
|
verbose_name_plural = verbose_name
|
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
return self.name
|
|
|
|
|
|
|
|
|
|
# 吴铠涛:侧边栏模型
|
|
|
|
|
|
|
|
|
|
class SideBar(models.Model):
|
|
|
|
|
"""侧边栏,可以展示一些html内容"""
|
|
|
|
|
name = models.CharField(_('title'), max_length=100) # 吴铠涛:侧边栏标题
|
|
|
|
|
content = models.TextField(_('content')) # 吴铠涛:侧边栏内容
|
|
|
|
|
sequence = models.IntegerField(_('order'), unique=True) # 吴铠涛:排序序号
|
|
|
|
|
is_enable = models.BooleanField(_('is enable'), default=True) # 吴铠涛:是否启用
|
|
|
|
|
name = models.CharField(_('title'), max_length=100)
|
|
|
|
|
content = models.TextField(_('content'))
|
|
|
|
|
sequence = models.IntegerField(_('order'), unique=True)
|
|
|
|
|
is_enable = models.BooleanField(_('is enable'), default=True)
|
|
|
|
|
creation_time = models.DateTimeField(_('creation time'), default=now)
|
|
|
|
|
last_mod_time = models.DateTimeField(_('modify time'), default=now)
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
ordering = ['sequence'] # 吴铠涛:按序号排序
|
|
|
|
|
ordering = ['sequence']
|
|
|
|
|
verbose_name = _('sidebar')
|
|
|
|
|
verbose_name_plural = verbose_name
|
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
return self.name
|
|
|
|
|
|
|
|
|
|
# 吴铠涛:博客设置模型
|
|
|
|
|
|
|
|
|
|
class BlogSettings(models.Model):
|
|
|
|
|
"""blog的配置"""
|
|
|
|
|
site_name = models.CharField(
|
|
|
|
|
@ -319,53 +311,53 @@ class BlogSettings(models.Model):
|
|
|
|
|
max_length=200,
|
|
|
|
|
null=False,
|
|
|
|
|
blank=False,
|
|
|
|
|
default='') # 吴铠涛:站点名称
|
|
|
|
|
default='')
|
|
|
|
|
site_description = models.TextField(
|
|
|
|
|
_('site description'),
|
|
|
|
|
max_length=1000,
|
|
|
|
|
null=False,
|
|
|
|
|
blank=False,
|
|
|
|
|
default='') # 吴铠涛:站点描述
|
|
|
|
|
default='')
|
|
|
|
|
site_seo_description = models.TextField(
|
|
|
|
|
_('site seo description'), max_length=1000, null=False, blank=False, default='') # 吴铠涛:SEO描述
|
|
|
|
|
_('site seo description'), max_length=1000, null=False, blank=False, default='')
|
|
|
|
|
site_keywords = models.TextField(
|
|
|
|
|
_('site keywords'),
|
|
|
|
|
max_length=1000,
|
|
|
|
|
null=False,
|
|
|
|
|
blank=False,
|
|
|
|
|
default='') # 吴铠涛:站点关键词
|
|
|
|
|
article_sub_length = models.IntegerField(_('article sub length'), default=300) # 吴铠涛:文章摘要长度
|
|
|
|
|
sidebar_article_count = models.IntegerField(_('sidebar article count'), default=10) # 吴铠涛:侧边栏文章数量
|
|
|
|
|
sidebar_comment_count = models.IntegerField(_('sidebar comment count'), default=5) # 吴铠涛:侧边栏评论数量
|
|
|
|
|
article_comment_count = models.IntegerField(_('article comment count'), default=5) # 吴铠涛:文章评论数量
|
|
|
|
|
show_google_adsense = models.BooleanField(_('show adsense'), default=False) # 吴铠涛:是否显示Google广告
|
|
|
|
|
default='')
|
|
|
|
|
article_sub_length = models.IntegerField(_('article sub length'), default=300)
|
|
|
|
|
sidebar_article_count = models.IntegerField(_('sidebar article count'), default=10)
|
|
|
|
|
sidebar_comment_count = models.IntegerField(_('sidebar comment count'), default=5)
|
|
|
|
|
article_comment_count = models.IntegerField(_('article comment count'), default=5)
|
|
|
|
|
show_google_adsense = models.BooleanField(_('show adsense'), default=False)
|
|
|
|
|
google_adsense_codes = models.TextField(
|
|
|
|
|
_('adsense code'), max_length=2000, null=True, blank=True, default='') # 吴铠涛:Google广告代码
|
|
|
|
|
open_site_comment = models.BooleanField(_('open site comment'), default=True) # 吴铠涛:是否开启站点评论
|
|
|
|
|
global_header = models.TextField("公共头部", null=True, blank=True, default='') # 吴铠涛:全局头部HTML
|
|
|
|
|
global_footer = models.TextField("公共尾部", null=True, blank=True, default='') # 吴铠涛:全局尾部HTML
|
|
|
|
|
_('adsense code'), max_length=2000, null=True, blank=True, default='')
|
|
|
|
|
open_site_comment = models.BooleanField(_('open site comment'), default=True)
|
|
|
|
|
global_header = models.TextField("公共头部", null=True, blank=True, default='')
|
|
|
|
|
global_footer = models.TextField("公共尾部", null=True, blank=True, default='')
|
|
|
|
|
beian_code = models.CharField(
|
|
|
|
|
'备案号',
|
|
|
|
|
max_length=2000,
|
|
|
|
|
null=True,
|
|
|
|
|
blank=True,
|
|
|
|
|
default='') # 吴铠涛:备案号
|
|
|
|
|
default='')
|
|
|
|
|
analytics_code = models.TextField(
|
|
|
|
|
"网站统计代码",
|
|
|
|
|
max_length=1000,
|
|
|
|
|
null=False,
|
|
|
|
|
blank=False,
|
|
|
|
|
default='') # 吴铠涛:网站统计代码
|
|
|
|
|
default='')
|
|
|
|
|
show_gongan_code = models.BooleanField(
|
|
|
|
|
'是否显示公安备案号', default=False, null=False) # 吴铠涛:是否显示公安备案
|
|
|
|
|
'是否显示公安备案号', default=False, null=False)
|
|
|
|
|
gongan_beiancode = models.TextField(
|
|
|
|
|
'公安备案号',
|
|
|
|
|
max_length=2000,
|
|
|
|
|
null=True,
|
|
|
|
|
blank=True,
|
|
|
|
|
default='') # 吴铠涛:公安备案号
|
|
|
|
|
default='')
|
|
|
|
|
comment_need_review = models.BooleanField(
|
|
|
|
|
'评论是否需要审核', default=False, null=False) # 吴铠涛:评论是否需要审核
|
|
|
|
|
'评论是否需要审核', default=False, null=False)
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
verbose_name = _('Website configuration')
|
|
|
|
|
@ -381,4 +373,4 @@ class BlogSettings(models.Model):
|
|
|
|
|
def save(self, *args, **kwargs):
|
|
|
|
|
super().save(*args, **kwargs)
|
|
|
|
|
from djangoblog.utils import cache
|
|
|
|
|
cache.clear() # 吴铠涛:保存设置时清除缓存
|
|
|
|
|
cache.clear()
|
|
|
|
|
|