@ -1,122 +1,187 @@
#zf: 导入日志模块, 用于记录日志信息
import logging
import logging
#zf: 导入正则表达式模块, 用于匹配文章中的图片
import re
import re
#zf: 从abc模块导入abstractmethod装饰器
from abc import abstractmethod
from abc import abstractmethod
#zf: 导入Django配置模块
from django . conf import settings
from django . conf import settings
#zf: 导入Django验证错误异常
from django . core . exceptions import ValidationError
from django . core . exceptions import ValidationError
#zf: 导入Django数据库模型模块
from django . db import models
from django . db import models
#zf: 导入Django URL反向解析函数
from django . urls import reverse
from django . urls import reverse
#zf: 导入Django时区工具
from django . utils . timezone import now
from django . utils . timezone import now
#zf: 导入Django国际化翻译函数
from django . utils . translation import gettext_lazy as _
from django . utils . translation import gettext_lazy as _
#zf: 导入Markdown编辑器字段
from mdeditor . fields import MDTextField
from mdeditor . fields import MDTextField
#zf: 导入slugify函数, 用于生成slug
from uuslug import slugify
from uuslug import slugify
#zf: 从djangoblog.utils导入缓存装饰器和缓存工具
from djangoblog . utils import cache_decorator , cache
from djangoblog . utils import cache_decorator , cache
#zf: 从djangoblog.utils导入获取当前站点的函数
from djangoblog . utils import get_current_site
from djangoblog . utils import get_current_site
#zf: 创建日志记录器
logger = logging . getLogger ( __name__ )
logger = logging . getLogger ( __name__ )
#zf: 定义链接显示类型枚举类, 继承自TextChoices
class LinkShowType ( models . TextChoices ) :
class LinkShowType ( models . TextChoices ) :
I = ( ' i ' , _ ( ' index ' ) )
#zf: 首页显示
L = ( ' l ' , _ ( ' list ' ) )
I = ( ' i ' , _ ( ' index ' ) )
P = ( ' p ' , _ ( ' post ' ) )
#zf: 列表页显示
A = ( ' a ' , _ ( ' all ' ) )
L = ( ' l ' , _ ( ' list ' ) )
S = ( ' s ' , _ ( ' slide ' ) )
#zf: 文章页显示
P = ( ' p ' , _ ( ' post ' ) )
#zf: 全站显示
A = ( ' a ' , _ ( ' all ' ) )
#zf: 幻灯片显示
S = ( ' s ' , _ ( ' slide ' ) )
#zf: 定义基础模型类, 继承自Django的Model类
class BaseModel ( models . Model ) :
class BaseModel ( models . Model ) :
#zf: 主键字段
id = models . AutoField ( primary_key = True )
id = models . AutoField ( primary_key = True )
#zf: 创建时间字段
creation_time = models . DateTimeField ( _ ( ' creation time ' ) , default = now )
creation_time = models . DateTimeField ( _ ( ' creation time ' ) , default = now )
#zf: 最后修改时间字段
last_modify_time = models . DateTimeField ( _ ( ' modify time ' ) , default = now )
last_modify_time = models . DateTimeField ( _ ( ' modify time ' ) , default = now )
#zf: 重写save方法
def save ( self , * args , * * kwargs ) :
def save ( self , * args , * * kwargs ) :
#zf: 检查是否是更新文章浏览量的特殊情况
is_update_views = isinstance (
is_update_views = isinstance (
self ,
self ,
Article ) and ' update_fields ' in kwargs and kwargs [ ' update_fields ' ] == [ ' views ' ]
Article ) and ' update_fields ' in kwargs and kwargs [ ' update_fields ' ] == [ ' views ' ]
if is_update_views :
if is_update_views :
#zf: 如果是更新浏览量, 则直接更新数据库, 避免触发其他逻辑
Article . objects . filter ( pk = self . pk ) . update ( views = self . views )
Article . objects . filter ( pk = self . pk ) . update ( views = self . views )
else :
else :
#zf: 如果有slug字段, 则生成slug
if ' slug ' in self . __dict__ :
if ' slug ' in self . __dict__ :
slug = getattr (
slug = getattr (
self , ' title ' ) if ' title ' in self . __dict__ else getattr (
self , ' title ' ) if ' title ' in self . __dict__ else getattr (
self , ' name ' )
self , ' name ' )
setattr ( self , ' slug ' , slugify ( slug ) )
setattr ( self , ' slug ' , slugify ( slug ) )
#zf: 调用父类的save方法
super ( ) . save ( * args , * * kwargs )
super ( ) . save ( * args , * * kwargs )
#zf: 获取完整URL方法
def get_full_url ( self ) :
def get_full_url ( self ) :
#zf: 获取当前站点域名
site = get_current_site ( ) . domain
site = get_current_site ( ) . domain
#zf: 拼接完整URL
url = " https:// {site} {path} " . format ( site = site ,
url = " https:// {site} {path} " . format ( site = site ,
path = self . get_absolute_url ( ) )
path = self . get_absolute_url ( ) )
return url
return url
#zf: 设置为抽象类
class Meta :
class Meta :
abstract = True
abstract = True
#zf: 定义抽象方法, 子类必须实现
@abstractmethod
@abstractmethod
def get_absolute_url ( self ) :
def get_absolute_url ( self ) :
pass
pass
#zf: 定义文章模型类, 继承自BaseModel
class Article ( BaseModel ) :
class Article ( BaseModel ) :
""" 文章 """
""" 文章 """
#zf: 文章状态选项
STATUS_CHOICES = (
STATUS_CHOICES = (
( ' d ' , _ ( ' Draft ' ) ) ,
#zf: 草稿
( ' p ' , _ ( ' Published ' ) ) ,
( ' d ' , _ ( ' Draft ' ) ) ,
#zf: 已发布
( ' p ' , _ ( ' Published ' ) ) ,
)
)
#zf: 评论状态选项
COMMENT_STATUS = (
COMMENT_STATUS = (
( ' o ' , _ ( ' Open ' ) ) ,
#zf: 开启评论
( ' c ' , _ ( ' Close ' ) ) ,
( ' o ' , _ ( ' Open ' ) ) ,
#zf: 关闭评论
( ' c ' , _ ( ' Close ' ) ) ,
)
)
#zf: 文章类型选项
TYPE = (
TYPE = (
( ' a ' , _ ( ' Article ' ) ) ,
#zf: 文章
( ' p ' , _ ( ' Page ' ) ) ,
( ' a ' , _ ( ' Article ' ) ) ,
#zf: 页面
( ' p ' , _ ( ' Page ' ) ) ,
)
)
#zf: 标题字段
title = models . CharField ( _ ( ' title ' ) , max_length = 200 , unique = True )
title = models . CharField ( _ ( ' title ' ) , max_length = 200 , unique = True )
#zf: 正文字段, 使用Markdown编辑器
body = MDTextField ( _ ( ' body ' ) )
body = MDTextField ( _ ( ' body ' ) )
#zf: 发布时间字段
pub_time = models . DateTimeField (
pub_time = models . DateTimeField (
_ ( ' publish time ' ) , blank = False , null = False , default = now )
_ ( ' publish time ' ) , blank = False , null = False , default = now )
#zf: 状态字段
status = models . CharField (
status = models . CharField (
_ ( ' status ' ) ,
_ ( ' status ' ) ,
max_length = 1 ,
max_length = 1 ,
choices = STATUS_CHOICES ,
choices = STATUS_CHOICES ,
default = ' p ' )
default = ' p ' )
#zf: 评论状态字段
comment_status = models . CharField (
comment_status = models . CharField (
_ ( ' comment status ' ) ,
_ ( ' comment status ' ) ,
max_length = 1 ,
max_length = 1 ,
choices = COMMENT_STATUS ,
choices = COMMENT_STATUS ,
default = ' o ' )
default = ' o ' )
#zf: 类型字段
type = models . CharField ( _ ( ' type ' ) , max_length = 1 , choices = TYPE , default = ' a ' )
type = models . CharField ( _ ( ' type ' ) , max_length = 1 , choices = TYPE , default = ' a ' )
#zf: 浏览量字段
views = models . PositiveIntegerField ( _ ( ' views ' ) , default = 0 )
views = models . PositiveIntegerField ( _ ( ' views ' ) , default = 0 )
#zf: 作者字段, 外键关联到用户模型
author = models . ForeignKey (
author = models . ForeignKey (
settings . AUTH_USER_MODEL ,
settings . AUTH_USER_MODEL ,
verbose_name = _ ( ' author ' ) ,
verbose_name = _ ( ' author ' ) ,
blank = False ,
blank = False ,
null = False ,
null = False ,
on_delete = models . CASCADE )
on_delete = models . CASCADE )
#zf: 文章排序字段
article_order = models . IntegerField (
article_order = models . IntegerField (
_ ( ' order ' ) , blank = False , null = False , default = 0 )
_ ( ' order ' ) , blank = False , null = False , default = 0 )
#zf: 是否显示目录字段
show_toc = models . BooleanField ( _ ( ' show toc ' ) , blank = False , null = False , default = False )
show_toc = models . BooleanField ( _ ( ' show toc ' ) , blank = False , null = False , default = False )
#zf: 分类字段, 外键关联到Category模型
category = models . ForeignKey (
category = models . ForeignKey (
' Category ' ,
' Category ' ,
verbose_name = _ ( ' category ' ) ,
verbose_name = _ ( ' category ' ) ,
on_delete = models . CASCADE ,
on_delete = models . CASCADE ,
blank = False ,
blank = False ,
null = False )
null = False )
#zf: 标签字段, 多对多关联到Tag模型
tags = models . ManyToManyField ( ' Tag ' , verbose_name = _ ( ' tag ' ) , blank = True )
tags = models . ManyToManyField ( ' Tag ' , verbose_name = _ ( ' tag ' ) , blank = True )
#zf: 将文章正文转换为字符串
def body_to_string ( self ) :
def body_to_string ( self ) :
return self . body
return self . body
#zf: 字符串表示方法
def __str__ ( self ) :
def __str__ ( self ) :
return self . title
return self . title
#zf: 模型元数据
class Meta :
class Meta :
ordering = [ ' -article_order ' , ' -pub_time ' ]
#zf: 排序规则
verbose_name = _ ( ' article ' )
ordering = [ ' -article_order ' , ' -pub_time ' ]
verbose_name_plural = verbose_name
#zf: 单数形式显示名称
get_latest_by = ' id '
verbose_name = _ ( ' article ' )
#zf: 复数形式显示名称
verbose_name_plural = verbose_name
#zf: latest()方法使用的字段
get_latest_by = ' id '
#zf: 获取绝对URL方法
def get_absolute_url ( self ) :
def get_absolute_url ( self ) :
return reverse ( ' blog:detailbyid ' , kwargs = {
return reverse ( ' blog:detailbyid ' , kwargs = {
' article_id ' : self . id ,
' article_id ' : self . id ,
@ -125,252 +190,364 @@ class Article(BaseModel):
' day ' : self . creation_time . day
' day ' : self . creation_time . day
} )
} )
#zf: 获取分类树方法, 使用缓存装饰器缓存10小时
@cache_decorator ( 60 * 60 * 10 )
@cache_decorator ( 60 * 60 * 10 )
def get_category_tree ( self ) :
def get_category_tree ( self ) :
#zf: 获取分类的分类树
tree = self . category . get_category_tree ( )
tree = self . category . get_category_tree ( )
#zf: 将分类名称和URL组成元组列表
names = list ( map ( lambda c : ( c . name , c . get_absolute_url ( ) ) , tree ) )
names = list ( map ( lambda c : ( c . name , c . get_absolute_url ( ) ) , tree ) )
return names
return names
#zf: 保存方法
def save ( self , * args , * * kwargs ) :
def save ( self , * args , * * kwargs ) :
super ( ) . save ( * args , * * kwargs )
super ( ) . save ( * args , * * kwargs )
#zf: 增加浏览量方法
def viewed ( self ) :
def viewed ( self ) :
self . views + = 1
self . views + = 1
self . save ( update_fields = [ ' views ' ] )
self . save ( update_fields = [ ' views ' ] )
#zf: 获取评论列表方法
def comment_list ( self ) :
def comment_list ( self ) :
#zf: 构造缓存键名
cache_key = ' article_comments_ {id} ' . format ( id = self . id )
cache_key = ' article_comments_ {id} ' . format ( id = self . id )
#zf: 从缓存中获取评论列表
value = cache . get ( cache_key )
value = cache . get ( cache_key )
if value :
if value :
#zf: 如果缓存中有数据, 记录日志并返回
logger . info ( ' get article comments: {id} ' . format ( id = self . id ) )
logger . info ( ' get article comments: {id} ' . format ( id = self . id ) )
return value
return value
else :
else :
#zf: 如果缓存中没有数据, 从数据库查询并缓存
comments = self . comment_set . filter ( is_enable = True ) . order_by ( ' -id ' )
comments = self . comment_set . filter ( is_enable = True ) . order_by ( ' -id ' )
cache . set ( cache_key , comments , 60 * 100 )
cache . set ( cache_key , comments , 60 * 100 )
logger . info ( ' set article comments: {id} ' . format ( id = self . id ) )
logger . info ( ' set article comments: {id} ' . format ( id = self . id ) )
return comments
return comments
#zf: 获取管理后台URL方法
def get_admin_url ( self ) :
def get_admin_url ( self ) :
#zf: 获取模型的app_label和model_name
info = ( self . _meta . app_label , self . _meta . model_name )
info = ( self . _meta . app_label , self . _meta . model_name )
#zf: 生成管理后台编辑页面的URL
return reverse ( ' admin: %s _ %s _change ' % info , args = ( self . pk , ) )
return reverse ( ' admin: %s _ %s _change ' % info , args = ( self . pk , ) )
#zf: 获取下一篇文章方法, 使用缓存装饰器缓存100分钟
@cache_decorator ( expiration = 60 * 100 )
@cache_decorator ( expiration = 60 * 100 )
def next_article ( self ) :
def next_article ( self ) :
# 下一篇
# zf: 下一篇
return Article . objects . filter (
return Article . objects . filter (
id__gt = self . id , status = ' p ' ) . order_by ( ' id ' ) . first ( )
id__gt = self . id , status = ' p ' ) . order_by ( ' id ' ) . first ( )
#zf: 获取上一篇文章方法, 使用缓存装饰器缓存100分钟
@cache_decorator ( expiration = 60 * 100 )
@cache_decorator ( expiration = 60 * 100 )
def prev_article ( self ) :
def prev_article ( self ) :
# 前一篇
# zf: 前一篇
return Article . objects . filter ( id__lt = self . id , status = ' p ' ) . first ( )
return Article . objects . filter ( id__lt = self . id , status = ' p ' ) . first ( )
#zf: 获取文章中第一张图片的URL方法
def get_first_image_url ( self ) :
def get_first_image_url ( self ) :
"""
"""
Get the first image url from article . body .
Get the first image url from article . body .
: return :
: return :
"""
"""
#zf: 使用正则表达式匹配Markdown图片语法
match = re . search ( r ' ! \ [.*? \ ] \ ((.+?) \ ) ' , self . body )
match = re . search ( r ' ! \ [.*? \ ] \ ((.+?) \ ) ' , self . body )
if match :
if match :
#zf: 如果匹配到图片, 返回图片URL
return match . group ( 1 )
return match . group ( 1 )
#zf: 如果没有匹配到图片, 返回空字符串
return " "
return " "
#zf: 定义分类模型类, 继承自BaseModel
class Category ( BaseModel ) :
class Category ( BaseModel ) :
""" 文章分类 """
""" 文章分类 """
#zf: 分类名称字段
name = models . CharField ( _ ( ' category name ' ) , max_length = 30 , unique = True )
name = models . CharField ( _ ( ' category name ' ) , max_length = 30 , unique = True )
#zf: 父级分类字段, 外键关联到自身
parent_category = models . ForeignKey (
parent_category = models . ForeignKey (
' self ' ,
' self ' ,
verbose_name = _ ( ' parent category ' ) ,
verbose_name = _ ( ' parent category ' ) ,
blank = True ,
blank = True ,
null = True ,
null = True ,
on_delete = models . CASCADE )
on_delete = models . CASCADE )
#zf: slug字段
slug = models . SlugField ( default = ' no-slug ' , max_length = 60 , blank = True )
slug = models . SlugField ( default = ' no-slug ' , max_length = 60 , blank = True )
#zf: 索引字段, 用于排序
index = models . IntegerField ( default = 0 , verbose_name = _ ( ' index ' ) )
index = models . IntegerField ( default = 0 , verbose_name = _ ( ' index ' ) )
#zf: 模型元数据
class Meta :
class Meta :
ordering = [ ' -index ' ]
#zf: 按索引降序排列
verbose_name = _ ( ' category ' )
ordering = [ ' -index ' ]
verbose_name_plural = verbose_name
#zf: 单数形式显示名称
verbose_name = _ ( ' category ' )
#zf: 复数形式显示名称
verbose_name_plural = verbose_name
#zf: 获取绝对URL方法
def get_absolute_url ( self ) :
def get_absolute_url ( self ) :
return reverse (
return reverse (
' blog:category_detail ' , kwargs = {
' blog:category_detail ' , kwargs = {
' category_name ' : self . slug } )
' category_name ' : self . slug } )
#zf: 字符串表示方法
def __str__ ( self ) :
def __str__ ( self ) :
return self . name
return self . name
#zf: 获取分类树方法, 使用缓存装饰器缓存10小时
@cache_decorator ( 60 * 60 * 10 )
@cache_decorator ( 60 * 60 * 10 )
def get_category_tree ( self ) :
def get_category_tree ( self ) :
"""
"""
递归获得分类目录的父级
递归获得分类目录的父级
: return :
: return :
"""
"""
#zf: 初始化分类列表
categorys = [ ]
categorys = [ ]
#zf: 递归解析分类树的内部函数
def parse ( category ) :
def parse ( category ) :
#zf: 将当前分类添加到列表
categorys . append ( category )
categorys . append ( category )
#zf: 如果有父级分类, 递归处理父级分类
if category . parent_category :
if category . parent_category :
parse ( category . parent_category )
parse ( category . parent_category )
#zf: 从当前分类开始解析
parse ( self )
parse ( self )
return categorys
return categorys
#zf: 获取子分类方法, 使用缓存装饰器缓存10小时
@cache_decorator ( 60 * 60 * 10 )
@cache_decorator ( 60 * 60 * 10 )
def get_sub_categorys ( self ) :
def get_sub_categorys ( self ) :
"""
"""
获得当前分类目录所有子集
获得当前分类目录所有子集
: return :
: return :
"""
"""
#zf: 初始化分类列表
categorys = [ ]
categorys = [ ]
#zf: 获取所有分类
all_categorys = Category . objects . all ( )
all_categorys = Category . objects . all ( )
#zf: 递归解析子分类的内部函数
def parse ( category ) :
def parse ( category ) :
#zf: 如果分类不在列表中, 添加到列表
if category not in categorys :
if category not in categorys :
categorys . append ( category )
categorys . append ( category )
#zf: 获取当前分类的子分类
childs = all_categorys . filter ( parent_category = category )
childs = all_categorys . filter ( parent_category = category )
#zf: 遍历子分类
for child in childs :
for child in childs :
#zf: 如果子分类不在列表中, 添加到列表
if category not in categorys :
if category not in categorys :
categorys . append ( child )
categorys . append ( child )
#zf: 递归处理子分类
parse ( child )
parse ( child )
#zf: 从当前分类开始解析
parse ( self )
parse ( self )
return categorys
return categorys
#zf: 定义标签模型类, 继承自BaseModel
class Tag ( BaseModel ) :
class Tag ( BaseModel ) :
""" 文章标签 """
""" 文章标签 """
#zf: 标签名称字段
name = models . CharField ( _ ( ' tag name ' ) , max_length = 30 , unique = True )
name = models . CharField ( _ ( ' tag name ' ) , max_length = 30 , unique = True )
#zf: slug字段
slug = models . SlugField ( default = ' no-slug ' , max_length = 60 , blank = True )
slug = models . SlugField ( default = ' no-slug ' , max_length = 60 , blank = True )
#zf: 字符串表示方法
def __str__ ( self ) :
def __str__ ( self ) :
return self . name
return self . name
#zf: 获取绝对URL方法
def get_absolute_url ( self ) :
def get_absolute_url ( self ) :
return reverse ( ' blog:tag_detail ' , kwargs = { ' tag_name ' : self . slug } )
return reverse ( ' blog:tag_detail ' , kwargs = { ' tag_name ' : self . slug } )
#zf: 获取文章数量方法, 使用缓存装饰器缓存10小时
@cache_decorator ( 60 * 60 * 10 )
@cache_decorator ( 60 * 60 * 10 )
def get_article_count ( self ) :
def get_article_count ( self ) :
#zf: 统计包含该标签的文章数量
return Article . objects . filter ( tags__name = self . name ) . distinct ( ) . count ( )
return Article . objects . filter ( tags__name = self . name ) . distinct ( ) . count ( )
#zf: 模型元数据
class Meta :
class Meta :
ordering = [ ' name ' ]
#zf: 按名称升序排列
verbose_name = _ ( ' tag ' )
ordering = [ ' name ' ]
verbose_name_plural = verbose_name
#zf: 单数形式显示名称
verbose_name = _ ( ' tag ' )
#zf: 复数形式显示名称
verbose_name_plural = verbose_name
#zf: 定义友情链接模型类
class Links ( models . Model ) :
class Links ( models . Model ) :
""" 友情链接 """
""" 友情链接 """
#zf: 链接名称字段
name = models . CharField ( _ ( ' link name ' ) , max_length = 30 , unique = True )
name = models . CharField ( _ ( ' link name ' ) , max_length = 30 , unique = True )
#zf: 链接地址字段
link = models . URLField ( _ ( ' link ' ) )
link = models . URLField ( _ ( ' link ' ) )
#zf: 排序字段
sequence = models . IntegerField ( _ ( ' order ' ) , unique = True )
sequence = models . IntegerField ( _ ( ' order ' ) , unique = True )
#zf: 是否显示字段
is_enable = models . BooleanField (
is_enable = models . BooleanField (
_ ( ' is show ' ) , default = True , blank = False , null = False )
_ ( ' is show ' ) , default = True , blank = False , null = False )
#zf: 显示类型字段
show_type = models . CharField (
show_type = models . CharField (
_ ( ' show type ' ) ,
_ ( ' show type ' ) ,
max_length = 1 ,
max_length = 1 ,
choices = LinkShowType . choices ,
choices = LinkShowType . choices ,
default = LinkShowType . I )
default = LinkShowType . I )
#zf: 创建时间字段
creation_time = models . DateTimeField ( _ ( ' creation time ' ) , default = now )
creation_time = models . DateTimeField ( _ ( ' creation time ' ) , default = now )
#zf: 最后修改时间字段
last_mod_time = models . DateTimeField ( _ ( ' modify time ' ) , default = now )
last_mod_time = models . DateTimeField ( _ ( ' modify time ' ) , default = now )
#zf: 模型元数据
class Meta :
class Meta :
ordering = [ ' sequence ' ]
#zf: 按排序字段升序排列
verbose_name = _ ( ' link ' )
ordering = [ ' sequence ' ]
verbose_name_plural = verbose_name
#zf: 单数形式显示名称
verbose_name = _ ( ' link ' )
#zf: 复数形式显示名称
verbose_name_plural = verbose_name
#zf: 字符串表示方法
def __str__ ( self ) :
def __str__ ( self ) :
return self . name
return self . name
#zf: 定义侧边栏模型类
class SideBar ( models . Model ) :
class SideBar ( models . Model ) :
""" 侧边栏,可以展示一些html内容 """
""" 侧边栏,可以展示一些html内容 """
#zf: 标题字段
name = models . CharField ( _ ( ' title ' ) , max_length = 100 )
name = models . CharField ( _ ( ' title ' ) , max_length = 100 )
#zf: 内容字段
content = models . TextField ( _ ( ' content ' ) )
content = models . TextField ( _ ( ' content ' ) )
#zf: 排序字段
sequence = models . IntegerField ( _ ( ' order ' ) , unique = True )
sequence = models . IntegerField ( _ ( ' order ' ) , unique = True )
#zf: 是否启用字段
is_enable = models . BooleanField ( _ ( ' is enable ' ) , default = True )
is_enable = models . BooleanField ( _ ( ' is enable ' ) , default = True )
#zf: 创建时间字段
creation_time = models . DateTimeField ( _ ( ' creation time ' ) , default = now )
creation_time = models . DateTimeField ( _ ( ' creation time ' ) , default = now )
#zf: 最后修改时间字段
last_mod_time = models . DateTimeField ( _ ( ' modify time ' ) , default = now )
last_mod_time = models . DateTimeField ( _ ( ' modify time ' ) , default = now )
#zf: 模型元数据
class Meta :
class Meta :
ordering = [ ' sequence ' ]
#zf: 按排序字段升序排列
verbose_name = _ ( ' sidebar ' )
ordering = [ ' sequence ' ]
verbose_name_plural = verbose_name
#zf: 单数形式显示名称
verbose_name = _ ( ' sidebar ' )
#zf: 复数形式显示名称
verbose_name_plural = verbose_name
#zf: 字符串表示方法
def __str__ ( self ) :
def __str__ ( self ) :
return self . name
return self . name
#zf: 定义博客设置模型类
class BlogSettings ( models . Model ) :
class BlogSettings ( models . Model ) :
""" blog的配置 """
""" blog的配置 """
#zf: 网站名称字段
site_name = models . CharField (
site_name = models . CharField (
_ ( ' site name ' ) ,
_ ( ' site name ' ) ,
max_length = 200 ,
max_length = 200 ,
null = False ,
null = False ,
blank = False ,
blank = False ,
default = ' ' )
default = ' ' )
#zf: 网站描述字段
site_description = models . TextField (
site_description = models . TextField (
_ ( ' site description ' ) ,
_ ( ' site description ' ) ,
max_length = 1000 ,
max_length = 1000 ,
null = False ,
null = False ,
blank = False ,
blank = False ,
default = ' ' )
default = ' ' )
#zf: 网站SEO描述字段
site_seo_description = models . TextField (
site_seo_description = models . TextField (
_ ( ' site seo description ' ) , max_length = 1000 , null = False , blank = False , default = ' ' )
_ ( ' site seo description ' ) , max_length = 1000 , null = False , blank = False , default = ' ' )
#zf: 网站关键词字段
site_keywords = models . TextField (
site_keywords = models . TextField (
_ ( ' site keywords ' ) ,
_ ( ' site keywords ' ) ,
max_length = 1000 ,
max_length = 1000 ,
null = False ,
null = False ,
blank = False ,
blank = False ,
default = ' ' )
default = ' ' )
#zf: 文章摘要长度字段
article_sub_length = models . IntegerField ( _ ( ' article sub length ' ) , default = 300 )
article_sub_length = models . IntegerField ( _ ( ' article sub length ' ) , default = 300 )
#zf: 侧边栏文章数量字段
sidebar_article_count = models . IntegerField ( _ ( ' sidebar article count ' ) , default = 10 )
sidebar_article_count = models . IntegerField ( _ ( ' sidebar article count ' ) , default = 10 )
#zf: 侧边栏评论数量字段
sidebar_comment_count = models . IntegerField ( _ ( ' sidebar comment count ' ) , default = 5 )
sidebar_comment_count = models . IntegerField ( _ ( ' sidebar comment count ' ) , default = 5 )
#zf: 文章页面默认显示评论数量字段
article_comment_count = models . IntegerField ( _ ( ' article comment count ' ) , default = 5 )
article_comment_count = models . IntegerField ( _ ( ' article comment count ' ) , default = 5 )
#zf: 是否显示谷歌广告字段
show_google_adsense = models . BooleanField ( _ ( ' show adsense ' ) , default = False )
show_google_adsense = models . BooleanField ( _ ( ' show adsense ' ) , default = False )
#zf: 谷歌广告代码字段
google_adsense_codes = models . TextField (
google_adsense_codes = models . TextField (
_ ( ' adsense code ' ) , max_length = 2000 , null = True , blank = True , default = ' ' )
_ ( ' adsense code ' ) , max_length = 2000 , null = True , blank = True , default = ' ' )
#zf: 是否开启网站评论功能字段
open_site_comment = models . BooleanField ( _ ( ' open site comment ' ) , default = True )
open_site_comment = models . BooleanField ( _ ( ' open site comment ' ) , default = True )
#zf: 全局头部内容字段
global_header = models . TextField ( " 公共头部 " , null = True , blank = True , default = ' ' )
global_header = models . TextField ( " 公共头部 " , null = True , blank = True , default = ' ' )
#zf: 全局尾部内容字段
global_footer = models . TextField ( " 公共尾部 " , null = True , blank = True , default = ' ' )
global_footer = models . TextField ( " 公共尾部 " , null = True , blank = True , default = ' ' )
#zf: 备案号字段
beian_code = models . CharField (
beian_code = models . CharField (
' 备案号 ' ,
' 备案号 ' ,
max_length = 2000 ,
max_length = 2000 ,
null = True ,
null = True ,
blank = True ,
blank = True ,
default = ' ' )
default = ' ' )
#zf: 网站统计代码字段
analytics_code = models . TextField (
analytics_code = models . TextField (
" 网站统计代码 " ,
" 网站统计代码 " ,
max_length = 1000 ,
max_length = 1000 ,
null = False ,
null = False ,
blank = False ,
blank = False ,
default = ' ' )
default = ' ' )
#zf: 是否显示公安备案号字段
show_gongan_code = models . BooleanField (
show_gongan_code = models . BooleanField (
' 是否显示公安备案号 ' , default = False , null = False )
' 是否显示公安备案号 ' , default = False , null = False )
#zf: 公安备案号字段
gongan_beiancode = models . TextField (
gongan_beiancode = models . TextField (
' 公安备案号 ' ,
' 公安备案号 ' ,
max_length = 2000 ,
max_length = 2000 ,
null = True ,
null = True ,
blank = True ,
blank = True ,
default = ' ' )
default = ' ' )
#zf: 评论是否需要审核字段
comment_need_review = models . BooleanField (
comment_need_review = models . BooleanField (
' 评论是否需要审核 ' , default = False , null = False )
' 评论是否需要审核 ' , default = False , null = False )
#zf: 模型元数据
class Meta :
class Meta :
verbose_name = _ ( ' Website configuration ' )
#zf: 单数形式显示名称
verbose_name_plural = verbose_name
verbose_name = _ ( ' Website configuration ' )
#zf: 复数形式显示名称
verbose_name_plural = verbose_name
#zf: 字符串表示方法
def __str__ ( self ) :
def __str__ ( self ) :
return self . site_name
return self . site_name
#zf: 数据验证方法
def clean ( self ) :
def clean ( self ) :
#zf: 检查是否已存在其他配置记录
if BlogSettings . objects . exclude ( id = self . id ) . count ( ) :
if BlogSettings . objects . exclude ( id = self . id ) . count ( ) :
#zf: 如果已存在其他配置记录, 抛出验证错误
raise ValidationError ( _ ( ' There can only be one configuration ' ) )
raise ValidationError ( _ ( ' There can only be one configuration ' ) )
#zf: 保存方法
def save ( self , * args , * * kwargs ) :
def save ( self , * args , * * kwargs ) :
#zf: 调用父类的保存方法
super ( ) . save ( * args , * * kwargs )
super ( ) . save ( * args , * * kwargs )
#zf: 导入缓存工具
from djangoblog . utils import cache
from djangoblog . utils import cache
cache . clear ( )
#zf: 清除所有缓存
cache . clear ( )