完善djangoblog包下的注释

wwc_branch
文翁晨 4 months ago
parent 7811db1947
commit 658a67da4e

@ -2,7 +2,7 @@
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.9 (BookManage)" jdkType="Python SDK" />
<orderEntry type="jdk" jdkName="Python 3.12 (DjangoBlog)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">

@ -1,3 +1,4 @@
#wwc
# 指定该 Django 应用的默认配置类。
# 'default_app_config' 是一个特殊变量Django 在加载应用时会自动识别它,
# 并使用指定的 AppConfig 子类来配置该应用的行为。

@ -5,20 +5,20 @@ from django.contrib.sites.admin import SiteAdmin
from django.contrib.sites.models import Site
# 导入各应用的 admin 配置和模型
from accounts.admin import * # 用户管理后台配置
from blog.admin import * # 博客功能后台配置
from blog.models import * # 博客功能模型
from comments.admin import * # 评论功能后台配置
from comments.models import * # 评论功能模型
from djangoblog.logentryadmin import LogEntryAdmin # 自定义的日志条目管理类
from oauth.admin import * # 第三方登录后台配置
from oauth.models import * # 第三方登录模型
from owntracks.admin import * # OwnTracks 位置追踪后台配置
from owntracks.models import * # OwnTracks 模型
from servermanager.admin import * # 服务器命令管理后台配置
from servermanager.models import * # 服务器命令模型
from ..accounts.admin import * # 用户管理后台配置
from ..blog.admin import * # 博客功能后台配置
from ..blog.models import * # 博客功能模型
from ..comments.admin import * # 评论功能后台配置
from ..comments.models import * # 评论功能模型
from ..djangoblog.logentryadmin import LogEntryAdmin # 自定义的日志条目管理类
from ..oauth.admin import * # 第三方登录后台配置
from ..oauth.models import * # 第三方登录模型
from ..owntracks.admin import * # OwnTracks 位置追踪后台配置
from ..owntracks.models import * # OwnTracks 模型
from ..servermanager.admin import * # 服务器命令管理后台配置
from ..servermanager.models import * # 服务器命令模型
#wwc
class DjangoBlogAdminSite(AdminSite):
"""
自定义 Django 管理后台站点类用于替代默认的 admin.site
@ -35,6 +35,7 @@ class DjangoBlogAdminSite(AdminSite):
site_header = 'djangoblog administration' # 浏览器标签和页面标题
site_title = 'djangoblog site admin' # 页面中显示的主标题
#wwc
def __init__(self, name='admin'):
"""
初始化自定义管理站点
@ -45,6 +46,7 @@ class DjangoBlogAdminSite(AdminSite):
"""
super().__init__(name) # 调用父类初始化方法
#wwc
def has_permission(self, request):
"""
重写权限检查方法控制谁可以访问此管理后台

@ -1,6 +1,6 @@
from django.apps import AppConfig
#wwc
class DjangoblogAppConfig(AppConfig):
"""
Django 应用配置类用于定义 'djangoblog' 应用的配置信息
@ -17,7 +17,7 @@ class DjangoblogAppConfig(AppConfig):
# 指定该应用的完整 Python 导入路径。
# 必须与应用在项目中的实际路径一致Django 通过此属性识别应用。
name = 'djangoblog'
#wwc
def ready(self):
"""
应用准备就绪时调用的方法

@ -9,12 +9,12 @@ from django.core.mail import EmailMultiAlternatives
from django.db.models.signals import post_save
from django.dispatch import receiver
from comments.models import Comment
from comments.utils import send_comment_email
from djangoblog.spider_notify import SpiderNotify
from djangoblog.utils import cache, expire_view_cache, delete_sidebar_cache, delete_view_cache
from djangoblog.utils import get_current_site
from oauth.models import OAuthUser
from ..comments.models import Comment
from ..comments.utils import send_comment_email
from ..djangoblog.spider_notify import SpiderNotify
from ..djangoblog.utils import cache, expire_view_cache, delete_sidebar_cache, delete_view_cache
from ..djangoblog.utils import get_current_site
from ..oauth.models import OAuthUser
# 获取当前模块的日志记录器,用于记录信号处理过程中的运行信息和错误
logger = logging.getLogger(__name__)
@ -32,7 +32,7 @@ oauth_user_login_signal = django.dispatch.Signal(['id'])
# - content: 邮件正文HTML
send_email_signal = django.dispatch.Signal(['emailto', 'title', 'content'])
#wwc
@receiver(send_email_signal)
def send_email_signal_handler(sender, **kwargs):
"""
@ -65,7 +65,7 @@ def send_email_signal_handler(sender, **kwargs):
msg.content_subtype = "html" # 设置内容类型为 HTML
# 创建邮件发送日志对象
from servermanager.models import EmailSendLog
from ..servermanager.models import EmailSendLog
log = EmailSendLog()
log.title = title
log.content = content
@ -82,7 +82,7 @@ def send_email_signal_handler(sender, **kwargs):
# 无论成功或失败,都保存日志记录
log.save()
#wwc
@receiver(oauth_user_login_signal)
def oauth_user_login_signal_handler(sender, **kwargs):
"""
@ -110,7 +110,7 @@ def oauth_user_login_signal_handler(sender, **kwargs):
# 登录后清理侧边栏缓存,确保用户信息等显示最新状态
delete_sidebar_cache()
#wwc
@receiver(post_save)
def model_post_save_callback(
sender,
@ -197,7 +197,7 @@ def model_post_save_callback(
if clearcache:
cache.clear()
#wwc
@receiver(user_logged_in)
@receiver(user_logged_out)
def user_auth_callback(sender, request, user, **kwargs):

@ -5,20 +5,20 @@ from haystack.forms import ModelSearchForm
from haystack.models import SearchResult
from haystack.utils import log as logging
from blog.documents import ArticleDocument, ArticleDocumentManager
from blog.models import Article
from ..blog.documents import ArticleDocument, ArticleDocumentManager
from ..blog.models import Article
# 获取当前模块的日志记录器,用于记录搜索相关的日志信息
logger = logging.getLogger(__name__)
#wwc
class ElasticSearchBackend(BaseSearchBackend):
"""
自定义 Elasticsearch 搜索后端继承自 Haystack BaseSearchBackend
负责与 Elasticsearch 交互实现索引的创建更新删除查询等操作
使用自定义的 ArticleDocumentManager 来管理文档索引
"""
#wwc
def __init__(self, connection_alias, **connection_options):
"""
初始化搜索后端
@ -30,7 +30,7 @@ class ElasticSearchBackend(BaseSearchBackend):
super(ElasticSearchBackend, self).__init__(connection_alias, **connection_options)
self.manager = ArticleDocumentManager() # 实例化文档管理器
self.include_spelling = True # 启用拼写建议功能
#wwc
def _get_models(self, iterable):
"""
将模型实例或查询集转换为可索引的文档对象列表
@ -44,7 +44,7 @@ class ElasticSearchBackend(BaseSearchBackend):
models = iterable if iterable and iterable[0] else Article.objects.all()
docs = self.manager.convert_to_doc(models)
return docs
#wwc
def _create(self, models):
"""
创建新的索引并填充数据
@ -55,7 +55,7 @@ class ElasticSearchBackend(BaseSearchBackend):
self.manager.create_index() # 创建索引结构
docs = self._get_models(models) # 转换为文档
self.manager.rebuild(docs) # 重建索引数据
#wwc
def _delete(self, models):
"""
从索引中删除指定的文档
@ -69,7 +69,7 @@ class ElasticSearchBackend(BaseSearchBackend):
for m in models:
m.delete() # 调用文档对象的 delete 方法
return True
#wwc
def _rebuild(self, models):
"""
重建索引如果 models 为空则重建所有文章索引
@ -80,7 +80,7 @@ class ElasticSearchBackend(BaseSearchBackend):
models = models if models else Article.objects.all()
docs = self.manager.convert_to_doc(models)
self.manager.update_docs(docs) # 更新文档到索引
#wwc
def update(self, index, iterable, commit=True):
"""
更新索引中的文档
@ -92,7 +92,7 @@ class ElasticSearchBackend(BaseSearchBackend):
"""
models = self._get_models(iterable)
self.manager.update_docs(models) # 将转换后的文档更新到索引
#wwc
def remove(self, obj_or_string):
"""
从索引中移除单个对象或字符串
@ -102,7 +102,7 @@ class ElasticSearchBackend(BaseSearchBackend):
"""
models = self._get_models([obj_or_string])
self._delete(models)
#wwc
def clear(self, models=None, commit=True):
"""
清空整个索引删除所有文档
@ -112,7 +112,7 @@ class ElasticSearchBackend(BaseSearchBackend):
commit: 是否立即提交未使用
"""
self.remove(None) # 调用 remove 方法清空
#wwc
@staticmethod
def get_suggestion(query: str) -> str:
"""
@ -138,7 +138,7 @@ class ElasticSearchBackend(BaseSearchBackend):
else:
keywords.append(suggest["text"]) # 无建议则使用原词
return ' '.join(keywords)
#wwc
@log_query
def search(self, query_string, **kwargs):
"""
@ -208,13 +208,13 @@ class ElasticSearchBackend(BaseSearchBackend):
'spelling_suggestion': spelling_suggestion, # 拼写建议
}
#wwc
class ElasticSearchQuery(BaseSearchQuery):
"""
自定义搜索查询类继承自 Haystack BaseSearchQuery
负责构建和处理搜索查询语句
"""
#wwc
def _convert_datetime(self, date):
"""
将日期时间对象转换为字符串格式用于索引查询
@ -229,7 +229,7 @@ class ElasticSearchQuery(BaseSearchQuery):
return force_str(date.strftime('%Y%m%d%H%M%S'))
else:
return force_str(date.strftime('%Y%m%d000000'))
#wwc
def clean(self, query_fragment):
"""
清理用户输入的查询片段防止特殊字符引发语法错误
@ -256,7 +256,7 @@ class ElasticSearchQuery(BaseSearchQuery):
cleaned_words.append(word)
return ' '.join(cleaned_words)
#wwc
def build_query_fragment(self, field, filter_type, value):
"""
构建查询片段此处直接返回 value.query_string
@ -270,7 +270,7 @@ class ElasticSearchQuery(BaseSearchQuery):
str: 查询字符串
"""
return value.query_string
#wwc
def get_count(self):
"""
获取搜索结果总数
@ -280,7 +280,7 @@ class ElasticSearchQuery(BaseSearchQuery):
"""
results = self.get_results()
return len(results) if results else 0
#wwc
def get_spelling_suggestion(self, preferred_query=None):
"""
获取拼写建议
@ -292,7 +292,7 @@ class ElasticSearchQuery(BaseSearchQuery):
str: 拼写建议
"""
return self._spelling_suggestion
#wwc
def build_params(self, spelling_query=None):
"""
构建传递给后端的参数字典
@ -306,13 +306,13 @@ class ElasticSearchQuery(BaseSearchQuery):
kwargs = super(ElasticSearchQuery, self).build_params(spelling_query=spelling_query)
return kwargs
#wwc
class ElasticSearchModelSearchForm(ModelSearchForm):
"""
自定义搜索表单继承自 Haystack ModelSearchForm
用于处理用户提交的搜索请求支持启用/禁用拼写建议
"""
#wwc
def search(self):
"""
重写 search 方法在搜索前设置是否启用拼写建议
@ -325,7 +325,7 @@ class ElasticSearchModelSearchForm(ModelSearchForm):
sqs = super().search()
return sqs
#wwc
class ElasticSearchEngine(BaseEngine):
"""
自定义搜索引擎集成 BackendQuery Form

@ -3,10 +3,10 @@ from django.contrib.syndication.views import Feed
from django.utils import timezone
from django.utils.feedgenerator import Rss201rev2Feed
from blog.models import Article
from djangoblog.utils import CommonMarkdown
from ..blog.models import Article
from ..djangoblog.utils import CommonMarkdown
#wwc
class DjangoBlogFeed(Feed):
"""
RSS 订阅源生成器继承自 Django Feed
@ -24,7 +24,7 @@ class DjangoBlogFeed(Feed):
# 订阅源的相对 URL 路径
link = "/feed/"
#wwc
def author_name(self):
"""
获取订阅源作者的名称
@ -35,7 +35,7 @@ class DjangoBlogFeed(Feed):
str: 作者昵称nickname
"""
return get_user_model().objects.first().nickname
#wwc
def author_link(self):
"""
获取订阅源作者的个人主页链接
@ -46,7 +46,7 @@ class DjangoBlogFeed(Feed):
str: 作者主页的 URL
"""
return get_user_model().objects.first().get_absolute_url()
#wwc
def items(self):
"""
获取订阅源包含的文章列表
@ -58,7 +58,7 @@ class DjangoBlogFeed(Feed):
QuerySet: 包含最多 5 篇最新文章的查询集
"""
return Article.objects.filter(type='a', status='p').order_by('-pub_time')[:5]
#wwc
def item_title(self, item):
"""
获取每篇文章在订阅源中的标题
@ -70,7 +70,7 @@ class DjangoBlogFeed(Feed):
str: 文章标题
"""
return item.title
#wwc
def item_description(self, item):
"""
获取每篇文章在订阅源中的描述内容
@ -85,7 +85,7 @@ class DjangoBlogFeed(Feed):
str: 渲染后的 HTML 内容
"""
return CommonMarkdown.get_markdown(item.body)
#wwc
def feed_copyright(self):
"""
获取订阅源的版权信息
@ -97,7 +97,7 @@ class DjangoBlogFeed(Feed):
"""
now = timezone.now()
return "Copyright© {year} 且听风吟".format(year=now.year)
#wwc
def item_link(self, item):
"""
获取每篇文章在订阅源中的链接
@ -111,7 +111,7 @@ class DjangoBlogFeed(Feed):
str: 文章的绝对 URL
"""
return item.get_absolute_url()
#wwc
def item_guid(self, item):
"""
获取每篇文章的全局唯一标识符GUID

@ -17,7 +17,7 @@ from django.utils.translation import gettext_lazy as _
# - mark_safe: 标记字符串为安全 HTML不转义
# - gettext_lazy: 国际化文本标记
#wwc
class LogEntryAdmin(admin.ModelAdmin):
"""
自定义 Django 管理后台中日志条目LogEntry的管理界面
@ -50,7 +50,7 @@ class LogEntryAdmin(admin.ModelAdmin):
'object_link', # 被操作的对象实例(带链接)
'get_change_message', # 操作详情消息
]
#wwc
def has_add_permission(self, request):
"""
控制是否允许添加新的日志条目
@ -64,7 +64,7 @@ class LogEntryAdmin(admin.ModelAdmin):
bool: 始终返回 False禁止添加权限
"""
return False
#wwc
def has_change_permission(self, request, obj=None):
"""
控制是否允许修改日志条目
@ -83,7 +83,7 @@ class LogEntryAdmin(admin.ModelAdmin):
request.user.is_superuser or
request.user.has_perm('admin.change_logentry')
) and request.method != 'POST'
#wwc
def has_delete_permission(self, request, obj=None):
"""
控制是否允许删除日志条目
@ -98,7 +98,7 @@ class LogEntryAdmin(admin.ModelAdmin):
bool: 始终返回 False禁止删除权限
"""
return False
#wwc
def object_link(self, obj):
"""
将被操作对象的名称转换为可点击的超链接如果可能
@ -133,7 +133,7 @@ class LogEntryAdmin(admin.ModelAdmin):
object_link.admin_order_field = 'object_repr'
# 设置此字段在列表页显示的列标题(支持国际化)
object_link.short_description = _('object')
#wwc
def user_link(self, obj):
"""
将操作用户的名称转换为可点击的超链接指向该用户在管理后台的编辑页面
@ -163,7 +163,7 @@ class LogEntryAdmin(admin.ModelAdmin):
user_link.admin_order_field = 'user'
# 设置此字段在列表页显示的列标题(支持国际化)
user_link.short_description = _('user')
#wwc
def get_queryset(self, request):
"""
自定义查询集优化数据库查询性能
@ -179,7 +179,7 @@ class LogEntryAdmin(admin.ModelAdmin):
"""
queryset = super(LogEntryAdmin, self).get_queryset(request)
return queryset.prefetch_related('content_type')
#wwc
def get_actions(self, request):
"""
自定义可用的操作列表如批量删除

@ -3,18 +3,21 @@ import logging
logger = logging.getLogger(__name__)
#wwc
class BasePlugin:
# 插件元数据
PLUGIN_NAME = None
PLUGIN_DESCRIPTION = None
PLUGIN_VERSION = None
#wwc
def __init__(self):
if not all([self.PLUGIN_NAME, self.PLUGIN_DESCRIPTION, self.PLUGIN_VERSION]):
raise ValueError("Plugin metadata (PLUGIN_NAME, PLUGIN_DESCRIPTION, PLUGIN_VERSION) must be defined.")
self.init_plugin()
self.register_hooks()
#wwc
def init_plugin(self):
"""
插件初始化逻辑
@ -22,6 +25,7 @@ class BasePlugin:
"""
logger.info(f'{self.PLUGIN_NAME} initialized.')
#wwc
def register_hooks(self):
"""
注册插件钩子
@ -29,6 +33,7 @@ class BasePlugin:
"""
pass
#wwc
def get_plugin_info(self):
"""
获取插件信息

@ -1,3 +1,4 @@
#wwc
# 定义一个常量,表示“加载文章详情”的动作类型或事件标识。
# 通常用于状态管理、事件分发或日志记录中,标识当前操作是获取或展示某篇文章的详细内容。
ARTICLE_DETAIL_LOAD = 'article_detail_load'

@ -4,7 +4,7 @@ logger = logging.getLogger(__name__)
_hooks = {}
#wwc
def register(hook_name: str, callback: callable):
"""
注册一个钩子回调
@ -14,7 +14,7 @@ def register(hook_name: str, callback: callable):
_hooks[hook_name].append(callback)
logger.debug(f"Registered hook '{hook_name}' with callback '{callback.__name__}'")
#wwc
def run_action(hook_name: str, *args, **kwargs):
"""
执行一个 Action Hook
@ -28,7 +28,7 @@ def run_action(hook_name: str, *args, **kwargs):
except Exception as e:
logger.error(f"Error running action hook '{hook_name}' callback '{callback.__name__}': {e}", exc_info=True)
#wwc
def apply_filters(hook_name: str, value, *args, **kwargs):
"""
执行一个 Filter Hook

@ -5,7 +5,7 @@ from django.conf import settings
# 获取当前模块的日志记录器,用于输出插件加载过程中的日志信息(如成功或失败记录)
logger = logging.getLogger(__name__)
#wwc
def load_plugins():
"""
动态加载并初始化插件

@ -1,9 +1,9 @@
from django.contrib.sitemaps import Sitemap
from django.urls import reverse
from blog.models import Article, Category, Tag
from ..blog.models import Article, Category, Tag
#wwc
class StaticViewSitemap(Sitemap):
"""
静态页面的站点地图Sitemap
@ -14,7 +14,7 @@ class StaticViewSitemap(Sitemap):
priority = 0.5
# 默认更新频率:每天
changefreq = 'daily'
#wwc
def items(self):
"""
定义需要包含在 sitemap 中的静态视图名称列表
@ -23,7 +23,7 @@ class StaticViewSitemap(Sitemap):
list: 包含 Django URL 命名的列表此处仅包含首页 'blog:index'
"""
return ['blog:index', ]
#wwc
def location(self, item):
"""
根据 items() 返回的 URL 名称生成对应的绝对路径
@ -36,7 +36,7 @@ class StaticViewSitemap(Sitemap):
"""
return reverse(item)
#wwc
class ArticleSiteMap(Sitemap):
"""
文章Article模型的站点地图类
@ -47,7 +47,7 @@ class ArticleSiteMap(Sitemap):
changefreq = "monthly"
# 优先级0.6(相对重要)
priority = "0.6"
#wwc
def items(self):
"""
获取所有已发布status='p'的文章对象
@ -56,7 +56,7 @@ class ArticleSiteMap(Sitemap):
QuerySet: 所有已发布文章的查询集
"""
return Article.objects.filter(status='p')
#wwc
def lastmod(self, obj):
"""
获取每篇文章的最后修改时间用于搜索引擎判断内容更新
@ -69,7 +69,7 @@ class ArticleSiteMap(Sitemap):
"""
return obj.last_modify_time
#wwc
class CategorySiteMap(Sitemap):
"""
分类Category模型的站点地图类
@ -80,7 +80,7 @@ class CategorySiteMap(Sitemap):
changefreq = "Weekly"
# 优先级0.6
priority = "0.6"
#wwc
def items(self):
"""
获取所有分类对象
@ -89,7 +89,7 @@ class CategorySiteMap(Sitemap):
QuerySet: 所有分类的查询集
"""
return Category.objects.all()
#wwc
def lastmod(self, obj):
"""
获取每个分类的最后修改时间
@ -102,7 +102,7 @@ class CategorySiteMap(Sitemap):
"""
return obj.last_modify_time
#wwc
class TagSiteMap(Sitemap):
"""
标签Tag模型的站点地图类
@ -113,7 +113,7 @@ class TagSiteMap(Sitemap):
changefreq = "Weekly"
# 优先级0.3(相对较低)
priority = "0.3"
#wwc
def items(self):
"""
获取所有标签对象
@ -122,7 +122,7 @@ class TagSiteMap(Sitemap):
QuerySet: 所有标签的查询集
"""
return Tag.objects.all()
#wwc
def lastmod(self, obj):
"""
获取每个标签的最后修改时间
@ -135,7 +135,7 @@ class TagSiteMap(Sitemap):
"""
return obj.last_modify_time
#wwc
class UserSiteMap(Sitemap):
"""
用户作者的站点地图类
@ -146,7 +146,7 @@ class UserSiteMap(Sitemap):
changefreq = "Weekly"
# 优先级0.3
priority = "0.3"
#wwc
def items(self):
"""
获取所有发布过文章的作者去重
@ -164,7 +164,7 @@ class UserSiteMap(Sitemap):
list: 去重后的用户作者对象列表
"""
return list(set(map(lambda x: x.author, Article.objects.all())))
#wwc
def lastmod(self, obj):
"""
获取每个用户的最后修改时间

@ -5,13 +5,13 @@ from django.conf import settings
# 获取当前模块的日志记录器,用于输出日志信息
logger = logging.getLogger(__name__)
#wwc
class SpiderNotify():
"""
蜘蛛推送通知工具类用于向搜索引擎如百度主动推送网站新内容的URL
帮助搜索引擎更快发现和收录网页
"""
#wwc
@staticmethod
def baidu_notify(urls):
"""
@ -40,7 +40,7 @@ class SpiderNotify():
logger.info(result.text) # 记录百度服务器返回的响应内容(如成功/失败信息)
except Exception as e:
logger.error(e) # 记录请求过程中发生的任何异常(如网络错误、超时等)
#wwc
@staticmethod
def notify(url):
"""

@ -1,9 +1,9 @@
from django.test import TestCase
# 从项目工具模块导入所有工具函数和类,用于测试
from djangoblog.utils import *
from ..djangoblog.utils import *
#wwc
class DjangoBlogTest(TestCase):
"""
DjangoBlog 应用的测试用例基类目前仅包含工具函数测试
@ -18,7 +18,7 @@ class DjangoBlogTest(TestCase):
若后续需要创建测试数据如用户文章等可在此方法中完成
"""
pass
#wwc
def test_utils(self):
"""
测试工具模块djangoblog.utils中的核心功能

@ -14,13 +14,13 @@ from django.urls import re_path # 支持正则表达式匹配的 URL 映射
from haystack.views import search_view_factory # Haystack 搜索框架的视图工厂
# 导入项目内自定义组件
from blog.views import EsSearchView # 自定义的 Elasticsearch 搜索视图
from djangoblog.admin_site import admin_site # 自定义的 Django 管理后台实例
from djangoblog.elasticsearch_backend import ElasticSearchModelSearchForm # 搜索表单类
from djangoblog.feeds import DjangoBlogFeed # RSS 订阅源
from djangoblog.sitemap import ArticleSiteMap, CategorySiteMap, StaticViewSitemap, TagSiteMap, UserSiteMap # 站点地图类
from ..blog.views import EsSearchView # 自定义的 Elasticsearch 搜索视图
from ..djangoblog.admin_site import admin_site # 自定义的 Django 管理后台实例
from ..djangoblog.elasticsearch_backend import ElasticSearchModelSearchForm # 搜索表单类
from ..djangoblog.feeds import DjangoBlogFeed # RSS 订阅源
from ..djangoblog.sitemap import ArticleSiteMap, CategorySiteMap, StaticViewSitemap, TagSiteMap, UserSiteMap # 站点地图类
#wwc
# 定义站点地图sitemap的映射字典
# 将不同的 sitemap 类按类别注册,用于生成 sitemap.xml
sitemaps = {

@ -34,11 +34,11 @@ def get_max_articleid_commentid():
返回:
tuple: (最新文章的主键, 最新评论的主键)
"""
from blog.models import Article
from comments.models import Comment
from ..blog.models import Article
from ..comments.models import Comment
return (Article.objects.latest().pk, Comment.objects.latest().pk)
#wwc
def get_sha256(str):
"""
计算输入字符串的 SHA256 哈希值
@ -52,7 +52,7 @@ def get_sha256(str):
m = sha256(str.encode('utf-8'))
return m.hexdigest()
#wwc
def cache_decorator(expiration=3 * 60):
"""
缓存装饰器用于为函数添加缓存功能避免重复计算或数据库查询
@ -70,7 +70,7 @@ def cache_decorator(expiration=3 * 60):
4. 未命中则执行原函数将结果存入缓存并返回
5. 特殊处理返回值为 None 的情况避免缓存穿透
"""
#wwc
def wrapper(func):
def news(*args, **kwargs):
try:
@ -103,7 +103,7 @@ def cache_decorator(expiration=3 * 60):
return wrapper
#wwc
def expire_view_cache(path, servername, serverport, key_prefix=None):
"""
手动清除特定视图的缓存用于内容更新后刷新缓存
@ -137,7 +137,7 @@ def expire_view_cache(path, servername, serverport, key_prefix=None):
return True
return False
#wwc
@cache_decorator()
def get_current_site():
"""
@ -149,12 +149,12 @@ def get_current_site():
site = Site.objects.get_current()
return site
#wwc
class CommonMarkdown:
"""
提供统一的 Markdown 解析功能支持代码高亮目录生成等
"""
#wwc
@staticmethod
def _convert_markdown(value):
"""
@ -177,7 +177,7 @@ class CommonMarkdown:
body = md.convert(value)
toc = md.toc
return body, toc
#wwc
@staticmethod
def get_markdown_with_toc(value):
"""
@ -191,7 +191,7 @@ class CommonMarkdown:
"""
body, toc = CommonMarkdown._convert_markdown(value)
return body, toc
#wwc
@staticmethod
def get_markdown(value):
"""
@ -206,7 +206,7 @@ class CommonMarkdown:
body, toc = CommonMarkdown._convert_markdown(value)
return body
#wwc
def send_email(emailto, title, content):
"""
发送邮件的快捷方法通过 Django 信号机制解耦
@ -219,14 +219,14 @@ def send_email(emailto, title, content):
实现:
触发自定义的 send_email_signal 信号由信号处理器完成实际的邮件发送逻辑
"""
from djangoblog.blog_signals import send_email_signal
from ..djangoblog.blog_signals import send_email_signal
send_email_signal.send(
send_email.__class__,
emailto=emailto,
title=title,
content=content)
#wwc
def generate_code() -> str:
"""
生成一个 6 位的随机数字验证码
@ -236,7 +236,7 @@ def generate_code() -> str:
"""
return ''.join(random.sample(string.digits, 6))
#wwc
def parse_dict_to_url(dict):
"""
将字典转换为 URL 查询参数字符串键值对用 & 连接
@ -255,7 +255,7 @@ def parse_dict_to_url(dict):
for k, v in dict.items()])
return url
#wwc
def get_blog_setting():
"""
获取博客系统设置优先从缓存读取未命中则从数据库获取并缓存
@ -269,7 +269,7 @@ def get_blog_setting():
if value:
return value
else:
from blog.models import BlogSettings
from ..blog.models import BlogSettings
if not BlogSettings.objects.count():
setting = BlogSettings()
setting.site_name = 'djangoblog'
@ -291,7 +291,7 @@ def get_blog_setting():
cache.set('get_blog_setting', value)
return value
#wwc
def save_user_avatar(url):
"""
从指定 URL 下载用户头像并保存到本地静态文件目录
@ -329,7 +329,7 @@ def save_user_avatar(url):
logger.error(e)
return static('blog/img/avatar.png')
#wwc
def delete_sidebar_cache():
"""
清除侧边栏所有缓存
@ -340,13 +340,13 @@ def delete_sidebar_cache():
实现:
遍历 LinkShowType 的所有值删除以 'sidebar' 为前缀的缓存键
"""
from blog.models import LinkShowType
from ..blog.models import LinkShowType
keys = ["sidebar" + x for x in LinkShowType.values]
for k in keys:
logger.info('delete sidebar key:' + k)
cache.delete(k)
#wwc
def delete_view_cache(prefix, keys):
"""
删除基于模板片段缓存@cache的缓存
@ -362,7 +362,7 @@ def delete_view_cache(prefix, keys):
key = make_template_fragment_key(prefix, keys)
cache.delete(key)
#wwc
def get_resource_url():
"""
获取静态资源的基础 URL
@ -386,7 +386,7 @@ ALLOWED_TAGS = ['a', 'abbr', 'acronym', 'b', 'blockquote', 'code', 'em', 'i', 'l
'h2', 'p']
ALLOWED_ATTRIBUTES = {'a': ['href', 'title'], 'abbr': ['title'], 'acronym': ['title']}
#wwc
def sanitize_html(html):
"""
清理 HTML 内容移除不安全的标签和属性防止跨站脚本XSS攻击

@ -51,7 +51,7 @@ DATETIME_REGEX = re.compile(
LOCALS = threading.local()
LOCALS.RAM_STORE = None
#wwc
class WhooshHtmlFormatter(HtmlFormatter):
"""
自定义高亮格式化器使用简单标签包裹匹配关键词
@ -59,7 +59,7 @@ class WhooshHtmlFormatter(HtmlFormatter):
"""
template = '<%(tag)s>%(t)s</%(tag)s>'
#wwc
class WhooshSearchBackend(BaseSearchBackend):
"""
Whoosh 搜索后端实现类负责与 Whoosh 引擎交互执行索引搜索删除等操作
@ -79,7 +79,7 @@ class WhooshSearchBackend(BaseSearchBackend):
'\\', '+', '-', '&&', '||', '!', '(', ')', '{', '}',
'[', ']', '^', '"', '~', '*', '?', ':', '.',
)
#wwc
def __init__(self, connection_alias, **connection_options):
"""
初始化 Whoosh 后端连接
@ -100,7 +100,7 @@ class WhooshSearchBackend(BaseSearchBackend):
"You must specify a 'PATH' in your settings for connection '%s'." % connection_alias)
self.log = logging.getLogger('haystack') # 日志记录器
#wwc
def setup(self):
"""
初始化索引环境创建目录构建 schema打开或创建索引
@ -143,7 +143,7 @@ class WhooshSearchBackend(BaseSearchBackend):
self.index = self.storage.create_index(self.schema)
self.setup_complete = True
#wwc
def build_schema(self, fields):
"""
根据 Django 模型字段定义构建 Whoosh Schema索引结构
@ -188,7 +188,7 @@ class WhooshSearchBackend(BaseSearchBackend):
raise SearchBackendError("No fields were found in any search_indexes. Please correct this before attempting to search.")
return (content_field_name, Schema(**schema_fields))
#wwc
def update(self, index, iterable, commit=True):
"""
更新索引文档添加或更新
@ -224,7 +224,7 @@ class WhooshSearchBackend(BaseSearchBackend):
if len(iterable) > 0:
writer.commit() # 提交写入
#wwc
def remove(self, obj_or_string, commit=True):
"""
从索引中删除一个文档
@ -243,7 +243,7 @@ class WhooshSearchBackend(BaseSearchBackend):
if not self.silently_fail:
raise
self.log.error("Failed to remove document '%s' from Whoosh: %s", whoosh_id, e, exc_info=True)
#wwc
def clear(self, models=None, commit=True):
"""
清空索引可指定模型或清空全部
@ -273,7 +273,7 @@ class WhooshSearchBackend(BaseSearchBackend):
self.log.error("Failed to clear Whoosh index of models '%s': %s", ','.join(models_to_delete), e, exc_info=True)
else:
self.log.error("Failed to clear Whoosh index: %s", e, exc_info=True)
#wwc
def delete_index(self):
"""
彻底删除索引目录并重建
@ -283,7 +283,7 @@ class WhooshSearchBackend(BaseSearchBackend):
elif not self.use_file_storage:
self.storage.clean()
self.setup() # 重新初始化
#wwc
def optimize(self):
"""
优化索引合并段提升搜索性能
@ -292,7 +292,7 @@ class WhooshSearchBackend(BaseSearchBackend):
self.setup()
self.index = self.index.refresh()
self.index.optimize()
#wwc
def calculate_page(self, start_offset=0, end_offset=None):
"""
计算分页参数页码和每页数量适配 Whoosh 的分页机制
@ -307,7 +307,7 @@ class WhooshSearchBackend(BaseSearchBackend):
page_length = end_offset - start_offset
page_num = int(start_offset / page_length) + 1 # Whoosh 页码从 1 开始
return page_num, page_length
#wwc
@log_query
def search(self, query_string, sort_by=None, start_offset=0, end_offset=None, fields='', highlight=False,
facets=None, date_facets=None, query_facets=None, narrow_queries=None, spelling_query=None,
@ -432,7 +432,7 @@ class WhooshSearchBackend(BaseSearchBackend):
spelling_suggestion = self.create_spelling_suggestion(spelling_query or query_string) \
if self.include_spelling else None
return {'results': [], 'hits': 0, 'spelling_suggestion': spelling_suggestion}
#wwc
def more_like_this(self, model_instance, additional_query_string=None, start_offset=0, end_offset=None,
models=None, limit_to_registered_models=None, result_class=None, **kwargs):
"""
@ -501,7 +501,7 @@ class WhooshSearchBackend(BaseSearchBackend):
narrow_searcher.close()
return results
return {'results': [], 'hits': 0}
#wwc
def _process_results(self, raw_page, highlight=False, query_string='', spelling_query=None, result_class=None):
"""
处理原始搜索结果转换为 SearchResult 对象列表
@ -561,7 +561,7 @@ class WhooshSearchBackend(BaseSearchBackend):
'facets': facets,
'spelling_suggestion': spelling_suggestion,
}
#wwc
def create_spelling_suggestion(self, query_string):
"""
生成拼写纠错建议
@ -584,7 +584,7 @@ class WhooshSearchBackend(BaseSearchBackend):
if suggestions:
suggested_words.append(suggestions[0])
return ' '.join(suggested_words)
#wwc
def _from_python(self, value):
"""
Python 值转换为 Whoosh 可索引的字符串
@ -601,7 +601,7 @@ class WhooshSearchBackend(BaseSearchBackend):
else:
value = force_str(value)
return value
#wwc
def _to_python(self, value):
"""
Whoosh 存储的值转换回 Python 类型
@ -625,7 +625,7 @@ class WhooshSearchBackend(BaseSearchBackend):
pass
return value
#wwc
class WhooshSearchQuery(BaseSearchQuery):
"""
Whoosh 查询构建器负责将 Django 查询语法转换为 Whoosh 查询字符串
@ -637,7 +637,7 @@ class WhooshSearchQuery(BaseSearchQuery):
return force_str(date.strftime('%Y%m%d%H%M%S'))
else:
return force_str(date.strftime('%Y%m%d000000'))
#wwc
def clean(self, query_fragment):
"""
清理用户输入的查询片段避免保留字和字符引发语法错误
@ -653,7 +653,7 @@ class WhooshSearchQuery(BaseSearchQuery):
break
cleaned_words.append(word)
return ' '.join(cleaned_words)
#wwc
def build_query_fragment(self, field, filter_type, value):
"""
构建单个查询片段 "title:django" "pub_date:[20200101 TO 20201231]"
@ -729,7 +729,7 @@ class WhooshSearchQuery(BaseSearchQuery):
return u"%s%s" % (index_fieldname, query_frag)
#wwc
class WhooshEngine(BaseEngine):
"""
Haystack 引擎注册类绑定 Backend Query

Loading…
Cancel
Save