|
|
|
|
@ -15,9 +15,20 @@ from uuslug import slugify # 导入slug生成工具
|
|
|
|
|
from djangoblog.utils import cache_decorator, cache # 导入缓存相关工具
|
|
|
|
|
from djangoblog.utils import get_current_site # 导入获取当前站点信息的工具
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
logger = logging.getLogger(__name__) # 创建当前模块的日志记录器
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
=======
|
|
|
|
|
logger = logging.getLogger(__name__) #lxy 初始化日志记录器
|
|
|
|
|
>>>>>>> LXY_branch
|
|
|
|
|
|
|
|
|
|
class LinkShowType(models.TextChoices): #lxy 链接展示类型枚举
|
|
|
|
|
I = ('i', _('index')) #lxy 首页展示
|
|
|
|
|
L = ('l', _('list')) #lxy 列表页展示
|
|
|
|
|
P = ('p', _('post')) #lxy 文章页展示
|
|
|
|
|
A = ('a', _('all')) #lxy 所有页面展示
|
|
|
|
|
S = ('s', _('side')) #lxy 侧边栏展示
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
class LinkShowType(models.TextChoices):
|
|
|
|
|
#ymq:定义链接展示位置的枚举类
|
|
|
|
|
I = ('i', _('index')) # 首页展示
|
|
|
|
|
@ -49,17 +60,36 @@ class BaseModel(models.Model):
|
|
|
|
|
slug = getattr(
|
|
|
|
|
self, 'title') if 'title' in self.__dict__ else getattr(
|
|
|
|
|
self, 'name')
|
|
|
|
|
=======
|
|
|
|
|
class BaseModel(models.Model): #lxy 模型基类(公共字段)
|
|
|
|
|
id = models.AutoField(primary_key=True) #lxy 主键ID
|
|
|
|
|
creation_time = models.DateTimeField(_('creation time'), default=now) #lxy 创建时间
|
|
|
|
|
last_modify_time = models.DateTimeField(_('modify time'), default=now) #lxy 修改时间
|
|
|
|
|
|
|
|
|
|
def save(self, *args, **kwargs): #lxy 重写保存方法
|
|
|
|
|
# 判断是否是更新文章阅读量
|
|
|
|
|
is_update_views = isinstance(self, Article) and 'update_fields' in kwargs and kwargs['update_fields'] == ['views']
|
|
|
|
|
if is_update_views:
|
|
|
|
|
Article.objects.filter(pk=self.pk).update(views=self.views) #lxy 单独更新阅读量
|
|
|
|
|
else:
|
|
|
|
|
if 'slug' in self.__dict__: #lxy 若有slug字段,自动生成
|
|
|
|
|
slug = getattr(self, 'title') if 'title' in self.__dict__ else getattr(self, 'name')
|
|
|
|
|
>>>>>>> LXY_branch
|
|
|
|
|
setattr(self, 'slug', slugify(slug))
|
|
|
|
|
super().save(*args, **kwargs)
|
|
|
|
|
super().save(*args, **kwargs) #lxy 调用父类保存
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
def get_full_url(self):
|
|
|
|
|
#ymq:生成包含域名的完整URL
|
|
|
|
|
=======
|
|
|
|
|
def get_full_url(self): #lxy 获取完整URL
|
|
|
|
|
>>>>>>> LXY_branch
|
|
|
|
|
site = get_current_site().domain
|
|
|
|
|
url = "https://{site}{path}".format(site=site,
|
|
|
|
|
path=self.get_absolute_url())
|
|
|
|
|
url = "https://{site}{path}".format(site=site, path=self.get_absolute_url())
|
|
|
|
|
return url
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
abstract = True # 声明为抽象模型,不生成数据库表
|
|
|
|
|
|
|
|
|
|
@abstractmethod
|
|
|
|
|
@ -71,20 +101,39 @@ class BaseModel(models.Model):
|
|
|
|
|
class Article(BaseModel):
|
|
|
|
|
"""文章模型"""
|
|
|
|
|
# 状态选项:草稿/已发布
|
|
|
|
|
=======
|
|
|
|
|
abstract = True #lxy 抽象基类(不生成表)
|
|
|
|
|
|
|
|
|
|
@abstractmethod
|
|
|
|
|
def get_absolute_url(self): #lxy 抽象方法:获取对象URL
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
class Article(BaseModel): #lxy 文章模型
|
|
|
|
|
# 文章状态枚举
|
|
|
|
|
>>>>>>> LXY_branch
|
|
|
|
|
STATUS_CHOICES = (
|
|
|
|
|
('d', _('Draft')),
|
|
|
|
|
('p', _('Published')),
|
|
|
|
|
('d', _('Draft')), #lxy 草稿
|
|
|
|
|
('p', _('Published')), #lxy 已发布
|
|
|
|
|
)
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
# 评论状态选项:开启/关闭
|
|
|
|
|
=======
|
|
|
|
|
# 评论状态枚举
|
|
|
|
|
>>>>>>> LXY_branch
|
|
|
|
|
COMMENT_STATUS = (
|
|
|
|
|
('o', _('Open')),
|
|
|
|
|
('c', _('Close')),
|
|
|
|
|
('o', _('open')), #lxy 开放评论
|
|
|
|
|
('c', _('close')), #lxy 关闭评论
|
|
|
|
|
)
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
# 类型选项:文章/页面
|
|
|
|
|
=======
|
|
|
|
|
# 文章类型枚举
|
|
|
|
|
>>>>>>> LXY_branch
|
|
|
|
|
TYPE = (
|
|
|
|
|
('a', _('Article')),
|
|
|
|
|
('p', _('Page')),
|
|
|
|
|
('a', _('Article')), #lxy 文章
|
|
|
|
|
('p', _('Page')), #lxy 页面
|
|
|
|
|
)
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
title = models.CharField(_('title'), max_length=200, unique=True) # 文章标题
|
|
|
|
|
body = MDTextField(_('body')) # 文章内容(使用markdown编辑器)
|
|
|
|
|
@ -129,26 +178,64 @@ class Article(BaseModel):
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
ordering = ['-article_order', '-pub_time'] # 默认排序:先按排序号降序,再按发布时间降序
|
|
|
|
|
=======
|
|
|
|
|
title = models.CharField(_('title'), max_length=200, unique=True) #lxy 标题
|
|
|
|
|
body = MDTextField(_('body')) #lxy 正文(Markdown)
|
|
|
|
|
pub_time = models.DateTimeField(_('publish time'), blank=False, null=False, default=now) #lxy 发布时间
|
|
|
|
|
status = models.CharField(_('status'), max_length=1, choices=STATUS_CHOICES, default='p') #lxy 文章状态
|
|
|
|
|
comment_status = models.CharField(_('comment status'), max_length=1, choices=COMMENT_STATUS, default='o') #lxy 评论状态
|
|
|
|
|
type = models.CharField(_('type'), max_length=1, choices=TYPE, default='a') #lxy 文章类型
|
|
|
|
|
views = models.PositiveIntegerField(_('views'), default=0) #lxy 阅读量
|
|
|
|
|
author = models.ForeignKey( #lxy 关联作者
|
|
|
|
|
settings.AUTH_USER_MODEL, verbose_name=_('author'), blank=False, null=False, on_delete=models.CASCADE
|
|
|
|
|
)
|
|
|
|
|
article_order = models.IntegerField(_('order'), blank=False, null=False, default=0) #lxy 排序序号
|
|
|
|
|
show_toc = models.BooleanField(_('show toc'), blank=False, null=False, default=False) #lxy 是否显示目录
|
|
|
|
|
category = models.ForeignKey( #lxy 关联分类
|
|
|
|
|
'Category', verbose_name=_('category'), on_delete=models.CASCADE, blank=False, null=False
|
|
|
|
|
)
|
|
|
|
|
tags = models.ManyToManyField('Tag', verbose_name=_('tag'), blank=True) #lxy 关联标签(多对多)
|
|
|
|
|
|
|
|
|
|
def body_to_string(self): #lxy 正文转字符串
|
|
|
|
|
return self.body
|
|
|
|
|
|
|
|
|
|
def __str__(self): #lxy 实例字符串表示
|
|
|
|
|
return self.title
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
ordering = ['-article_order', '-pub_time'] #lxy 默认排序(倒序)
|
|
|
|
|
>>>>>>> LXY_branch
|
|
|
|
|
verbose_name = _('article')
|
|
|
|
|
verbose_name_plural = verbose_name
|
|
|
|
|
get_latest_by = 'id' # 按id获取最新记录
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
def get_absolute_url(self):
|
|
|
|
|
#ymq:生成文章详情页的URL
|
|
|
|
|
return reverse('blog:detailbyid', kwargs={
|
|
|
|
|
=======
|
|
|
|
|
def get_absolute_url(self): #lxy 文章详情页URL
|
|
|
|
|
return reverse('blog:detail', kwargs={
|
|
|
|
|
>>>>>>> LXY_branch
|
|
|
|
|
'article_id': self.id,
|
|
|
|
|
'year': self.creation_time.year,
|
|
|
|
|
'month': self.creation_time.month,
|
|
|
|
|
'day': self.creation_time.day
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
@cache_decorator(60 * 60 * 10) # 缓存10小时
|
|
|
|
|
def get_category_tree(self):
|
|
|
|
|
#ymq:获取当前文章所属分类的层级结构(含父级分类)
|
|
|
|
|
=======
|
|
|
|
|
@cache_decorator(60 * 60 * 10) #lxy 缓存10小时
|
|
|
|
|
def get_category_tree(self): #lxy 获取分类层级
|
|
|
|
|
>>>>>>> LXY_branch
|
|
|
|
|
tree = self.category.get_category_tree()
|
|
|
|
|
names = list(map(lambda c: (c.name, c.get_absolute_url()), tree))
|
|
|
|
|
return names
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
def save(self, *args, **kwargs):
|
|
|
|
|
#ymq:重写保存方法(可扩展自定义逻辑)
|
|
|
|
|
super().save(*args, **kwargs)
|
|
|
|
|
@ -160,12 +247,23 @@ class Article(BaseModel):
|
|
|
|
|
|
|
|
|
|
def comment_list(self):
|
|
|
|
|
#ymq:获取文章的评论列表(带缓存)
|
|
|
|
|
=======
|
|
|
|
|
def save(self, *args, **kwargs): #lxy 重写保存
|
|
|
|
|
super().save(*args, **kwargs)
|
|
|
|
|
|
|
|
|
|
def viewed(self): #lxy 阅读量+1
|
|
|
|
|
self.views += 1
|
|
|
|
|
self.save(update_fields=['views']) #lxy 仅更新阅读量
|
|
|
|
|
|
|
|
|
|
def comment_list(self): #lxy 获取文章评论
|
|
|
|
|
>>>>>>> LXY_branch
|
|
|
|
|
cache_key = 'article_comments_{id}'.format(id=self.id)
|
|
|
|
|
value = cache.get(cache_key)
|
|
|
|
|
if value:
|
|
|
|
|
logger.info('get article comments:{id}'.format(id=self.id))
|
|
|
|
|
return value
|
|
|
|
|
else:
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
comments = self.comment_set.filter(is_enable=True).order_by('-id')
|
|
|
|
|
cache.set(cache_key, comments, 60 * 100) # 缓存100分钟
|
|
|
|
|
logger.info('set article comments:{id}'.format(id=self.id))
|
|
|
|
|
@ -190,11 +288,40 @@ class Article(BaseModel):
|
|
|
|
|
def get_first_image_url(self):
|
|
|
|
|
"""从文章内容中提取第一张图片的URL"""
|
|
|
|
|
match = re.search(r'!\[.*?\]\((.+?)\)', self.body) # 匹配markdown图片语法
|
|
|
|
|
=======
|
|
|
|
|
comments = self.comment_set.filter(is_enable=True).order_by('-id') #lxy 过滤启用的评论
|
|
|
|
|
cache.set(cache_key, comments, 60 * 100) #lxy 缓存评论
|
|
|
|
|
logger.info('set article comments:{id}'.format(id=self.id))
|
|
|
|
|
return comments
|
|
|
|
|
|
|
|
|
|
def get_admin_url(self): #lxy 后台管理URL
|
|
|
|
|
info = (self._meta.app_label, self._meta.model_name)
|
|
|
|
|
return reverse('admin:%s_%s_change' % info, args=(self.pk,))
|
|
|
|
|
|
|
|
|
|
@cache_decorator(expiration=60 * 100) #lxy 缓存
|
|
|
|
|
def next_article(self): #lxy 获取下一篇文章
|
|
|
|
|
return Article.objects.filter(id__gt=self.id, status='p').order_by('id').first()
|
|
|
|
|
|
|
|
|
|
@cache_decorator(expiration=60 * 100) #lxy 缓存
|
|
|
|
|
def prev_article(self): #lxy 获取上一篇文章
|
|
|
|
|
return Article.objects.filter(id__lt=self.id, status='p').first()
|
|
|
|
|
|
|
|
|
|
def get_first_image_url(self): #lxy 获取正文第一张图URL
|
|
|
|
|
match = re.search(pattern=r'!\[.*?]\((.*?)\)', self.body)
|
|
|
|
|
>>>>>>> LXY_branch
|
|
|
|
|
if match:
|
|
|
|
|
return match.group(1)
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
class Category(BaseModel): # lxy 分类模型
|
|
|
|
|
name = models.CharField(_('category name'), max_length=30, unique=True) # lxy 分类名称
|
|
|
|
|
parent_category = models.ForeignKey( # lxy 父分类(自关联)
|
|
|
|
|
'self', verbose_name=_('parent category'), blank=True, null=True, on_delete=models.CASCADE
|
|
|
|
|
)
|
|
|
|
|
slug = models.SlugField(default='no-slug', max_length=60, blank=True) # lxy 别名
|
|
|
|
|
index = models.IntegerField(default=0, verbose_name=_('index')) # lxy 排序索引
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
class Category(BaseModel):
|
|
|
|
|
"""文章分类模型"""
|
|
|
|
|
name = models.CharField(_('category name'), max_length=30, unique=True) # 分类名称
|
|
|
|
|
@ -319,9 +446,127 @@ class SideBar(models.Model):
|
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
#ymq:模型实例的字符串表示(侧边栏标题)
|
|
|
|
|
=======
|
|
|
|
|
class Meta:
|
|
|
|
|
ordering = ['-index'] # lxy 按索引倒序
|
|
|
|
|
verbose_name = _('category')
|
|
|
|
|
verbose_name_plural = verbose_name
|
|
|
|
|
|
|
|
|
|
def get_absolute_url(self): # lxy 分类详情页URL
|
|
|
|
|
return reverse('blog:category_detail', kwargs={'category_name': self.slug})
|
|
|
|
|
|
|
|
|
|
def __str__(self): # lxy 实例字符串表示
|
|
|
|
|
return self.name
|
|
|
|
|
|
|
|
|
|
def get_category_tree(self): # lxy 获取分类层级链
|
|
|
|
|
categories = []
|
|
|
|
|
|
|
|
|
|
def parse(category):
|
|
|
|
|
categories.append(category)
|
|
|
|
|
if category.parent_category:
|
|
|
|
|
parse(category.parent_category)
|
|
|
|
|
|
|
|
|
|
parse(self)
|
|
|
|
|
return categories
|
|
|
|
|
|
|
|
|
|
@cache_decorator(60 * 60 * 10) # lxy 缓存
|
|
|
|
|
def get_sub_categories(self): # lxy 获取所有子分类
|
|
|
|
|
categories = []
|
|
|
|
|
all_categories = Category.objects.all()
|
|
|
|
|
|
|
|
|
|
def parse(category):
|
|
|
|
|
if category not in categories:
|
|
|
|
|
categories.append(category)
|
|
|
|
|
children = all_categories.filter(parent_category=category)
|
|
|
|
|
for child in children:
|
|
|
|
|
if category not in categories:
|
|
|
|
|
categories.append(child)
|
|
|
|
|
parse(child)
|
|
|
|
|
|
|
|
|
|
parse(self)
|
|
|
|
|
return categories
|
|
|
|
|
|
|
|
|
|
class Tag(BaseModel): #lxy 标签模型
|
|
|
|
|
name = models.CharField(_('tag name'), max_length=30, unique=True) #lxy 标签名称
|
|
|
|
|
slug = models.SlugField(default='no-slug', max_length=60, blank=True) #lxy 别名
|
|
|
|
|
|
|
|
|
|
def __str__(self): #lxy 实例字符串表示
|
|
|
|
|
return self.name
|
|
|
|
|
|
|
|
|
|
def get_absolute_url(self): #lxy 标签详情页URL
|
|
|
|
|
return reverse('blog:tag_detail', kwargs={'tag_name': self.slug})
|
|
|
|
|
|
|
|
|
|
@cache_decorator(60 * 60 * 10) #lxy 缓存
|
|
|
|
|
def get_article_count(self): #lxy 获取标签关联文章数
|
|
|
|
|
return Article.objects.filter(tags__name=self.name).distinct().count()
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
ordering = ['name'] #lxy 按名称排序
|
|
|
|
|
verbose_name = _('tag')
|
|
|
|
|
verbose_name_plural = verbose_name
|
|
|
|
|
|
|
|
|
|
class Links(models.Model): #lxy 友链模型
|
|
|
|
|
name = models.CharField(_('link name'), max_length=30, unique=True) #lxy 友链名称
|
|
|
|
|
link = models.URLField(_('link')) #lxy 友链地址
|
|
|
|
|
sequence = models.IntegerField(_('order'), unique=True) #lxy 排序序号
|
|
|
|
|
is_enable = models.BooleanField(_('is show'), default=True, blank=False, null=False) #lxy 是否启用
|
|
|
|
|
show_type = models.CharField( #lxy 展示类型
|
|
|
|
|
_('show type'), max_length=1, choices=LinkShowType.choices, default=LinkShowType.I
|
|
|
|
|
)
|
|
|
|
|
creation_time = models.DateTimeField(_('creation time'), default=now) #lxy 创建时间
|
|
|
|
|
last_mod_time = models.DateTimeField(_('modify time'), default=now) #lxy 修改时间
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
ordering = ['sequence'] #lxy 按序号排序
|
|
|
|
|
verbose_name = _('link')
|
|
|
|
|
verbose_name_plural = verbose_name
|
|
|
|
|
|
|
|
|
|
def __str__(self): #lxy 实例字符串表示
|
|
|
|
|
return self.name
|
|
|
|
|
|
|
|
|
|
class SideBar(models.Model): #lxy 侧边栏模型
|
|
|
|
|
name = models.CharField(_('title'), max_length=100) #lxy 侧边栏标题
|
|
|
|
|
content = models.TextField(_('content')) #lxy 侧边栏内容(HTML)
|
|
|
|
|
sequence = models.IntegerField(_('order'), unique=True) #lxy 排序序号
|
|
|
|
|
is_enable = models.BooleanField(_('is enable'), default=True) #lxy 是否启用
|
|
|
|
|
creation_time = models.DateTimeField(_('creation time'), default=now) #lxy 创建时间
|
|
|
|
|
last_mod_time = models.DateTimeField(_('modify time'), default=now) #lxy 修改时间
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
ordering = ['sequence'] #lxy 按序号排序
|
|
|
|
|
verbose_name = _('sidebar')
|
|
|
|
|
verbose_name_plural = verbose_name
|
|
|
|
|
|
|
|
|
|
def __str__(self): #lxy 实例字符串表示
|
|
|
|
|
>>>>>>> LXY_branch
|
|
|
|
|
return self.name
|
|
|
|
|
|
|
|
|
|
class BlogSettings(models.Model): # lxy 博客配置模型
|
|
|
|
|
site_name = models.CharField(_('site name'), blank=False, default='') # lxy 站点名称
|
|
|
|
|
site_description = models.TextField( # lxy 站点描述
|
|
|
|
|
_('site description'), max_length=1000, null=False, blank=False, default=''
|
|
|
|
|
)
|
|
|
|
|
site_seo_description = models.TextField( # lxy 站点SEO描述
|
|
|
|
|
_('site seo description'), max_length=1000, null=False, blank=False, default=''
|
|
|
|
|
)
|
|
|
|
|
site_keywords = models.TextField( # lxy 站点关键词
|
|
|
|
|
_('site keywords'), max_length=1000, null=False, blank=False, default=''
|
|
|
|
|
)
|
|
|
|
|
article_sub_length = models.IntegerField(_('article sub length'), default=300) # lxy 文章摘要长度
|
|
|
|
|
sidebar_article_count = models.IntegerField(_('sidebar article count'), default=10) # lxy 侧边栏文章数
|
|
|
|
|
sidebar_comment_count = models.IntegerField(_('sidebar comment count'), default=5) # lxy 侧边栏评论数
|
|
|
|
|
show_google_adsense = models.BooleanField(_('show adsense'), default=False) # lxy 是否显示谷歌广告
|
|
|
|
|
google_adsense_codes = models.TextField( # lxy 谷歌广告代码
|
|
|
|
|
_('adsense code'), max_length=2000, null=True, blank=True, default=''
|
|
|
|
|
)
|
|
|
|
|
open_site_comment = models.BooleanField(_('open site comment'), default=True) # lxy 是否开放站点评论
|
|
|
|
|
global_header = models.TextField("公共头部", null=True, blank=True, default='') # lxy 公共头部HTML
|
|
|
|
|
global_footer = models.TextField("公共底部", null=True, blank=True, default='') # lxy 公共底部HTML
|
|
|
|
|
beian_code = models.CharField( # lxy 备案号
|
|
|
|
|
'备案号', max_length=2000, null=True, blank=True, default=''
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
class BlogSettings(models.Model):
|
|
|
|
|
"""博客全局配置模型"""
|
|
|
|
|
site_name = models.CharField(
|
|
|
|
|
@ -361,10 +606,14 @@ class BlogSettings(models.Model):
|
|
|
|
|
blank=True,
|
|
|
|
|
default='') # 网站备案号
|
|
|
|
|
analytics_code = models.TextField(
|
|
|
|
|
=======
|
|
|
|
|
analytics_code = models.TextField( # lxy 网站统计代码
|
|
|
|
|
>>>>>>> LXY_branch
|
|
|
|
|
"网站统计代码",
|
|
|
|
|
max_length=1000,
|
|
|
|
|
null=False,
|
|
|
|
|
blank=False,
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
default='') # 统计分析代码
|
|
|
|
|
show_gongan_code = models.BooleanField(
|
|
|
|
|
'是否显示公安备案号', default=False, null=False) # 是否显示公安备案号
|
|
|
|
|
@ -376,22 +625,53 @@ class BlogSettings(models.Model):
|
|
|
|
|
default='') # 公安备案号
|
|
|
|
|
comment_need_review = models.BooleanField(
|
|
|
|
|
'评论是否需要审核', default=False, null=False) # 评论是否需要审核
|
|
|
|
|
=======
|
|
|
|
|
default=""
|
|
|
|
|
)
|
|
|
|
|
show_gongan_code = models.BooleanField( # lxy 是否显示公安备案号
|
|
|
|
|
"是否显示公安备案号", default=False, null=False
|
|
|
|
|
)
|
|
|
|
|
gongan_beiancode = models.TextField( # lxy 公安备案号
|
|
|
|
|
"公安备案号",
|
|
|
|
|
max_length=2000,
|
|
|
|
|
null=True,
|
|
|
|
|
blank=True,
|
|
|
|
|
default=""
|
|
|
|
|
)
|
|
|
|
|
comment_need_review = models.BooleanField( # lxy 评论是否需要审核
|
|
|
|
|
"评论是否需要审核", default=False, null=False
|
|
|
|
|
)
|
|
|
|
|
>>>>>>> LXY_branch
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
verbose_name = _('Website configuration')
|
|
|
|
|
verbose_name_plural = verbose_name
|
|
|
|
|
class Meta: # lxy 模型元信息
|
|
|
|
|
verbose_name = _('Website configuration') # lxy 单数名称
|
|
|
|
|
verbose_name_plural = verbose_name # lxy 复数名称
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
def __str__(self):
|
|
|
|
|
#ymq:模型实例的字符串表示(网站名称)
|
|
|
|
|
return self.site_name
|
|
|
|
|
|
|
|
|
|
def clean(self):
|
|
|
|
|
#ymq:数据验证,确保全局配置只能有一条记录
|
|
|
|
|
=======
|
|
|
|
|
def __str__(self): # lxy 实例字符串表示
|
|
|
|
|
return self.site_name
|
|
|
|
|
|
|
|
|
|
def clean(self): # lxy 数据校验(确保仅存在一个配置)
|
|
|
|
|
>>>>>>> LXY_branch
|
|
|
|
|
if BlogSettings.objects.exclude(id=self.id).count():
|
|
|
|
|
raise ValidationError(_('There can only be one configuration'))
|
|
|
|
|
raise ValidationError(_('There can only be one configuration')) # lxy 抛出唯一配置异常
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
def save(self, *args, **kwargs):
|
|
|
|
|
#ymq:保存配置后清除缓存,确保配置立即生效
|
|
|
|
|
super().save(*args, **kwargs)
|
|
|
|
|
from djangoblog.utils import cache
|
|
|
|
|
cache.clear()
|
|
|
|
|
cache.clear()
|
|
|
|
|
=======
|
|
|
|
|
def save(self, *args, **kwargs): # lxy 重写保存方法
|
|
|
|
|
super().save(*args, **kwargs) # lxy 调用父类保存
|
|
|
|
|
from djangoblog.utils import cache
|
|
|
|
|
cache.clear() # lxy 保存后清空缓存
|
|
|
|
|
>>>>>>> LXY_branch
|
|
|
|
|
|