From f0665a6c2f8cf4197bda3fe64726df0fbae1cb1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=94=B0=E6=B5=A9=E6=B1=A0?= <2314016651@qq.com> Date: Thu, 6 Nov 2025 00:50:20 +0800 Subject: [PATCH] blog part Annotation --- src/blog/admin.py | 40 ++++++++++++++++++++++++---------------- src/blog/forms.py | 14 ++++++++++---- src/blog/models.py | 29 ++++++++++++++++++++--------- src/blog/urls.py | 14 ++++++++++++++ src/blog/views.py | 28 +++++++++++++++------------- 5 files changed, 83 insertions(+), 42 deletions(-) diff --git a/src/blog/admin.py b/src/blog/admin.py index 46c3420..ee1bdac 100644 --- a/src/blog/admin.py +++ b/src/blog/admin.py @@ -1,3 +1,5 @@ + +# 导入Django管理后台相关模块 from django import forms from django.contrib import admin from django.contrib.auth import get_user_model @@ -5,44 +7,50 @@ from django.urls import reverse from django.utils.html import format_html from django.utils.translation import gettext_lazy as _ -# Register your models here. +# 注册模型 from .models import Article + +# 文章模型的自定义表单 class ArticleForm(forms.ModelForm): - # body = forms.CharField(widget=AdminPagedownWidget()) + # body = forms.CharField(widget=AdminPagedownWidget()) # 可选:使用自定义编辑器 class Meta: model = Article - fields = '__all__' + fields = '__all__' # 包含所有字段 + +# 批量操作:发布文章 def makr_article_publish(modeladmin, request, queryset): queryset.update(status='p') - +# 批量操作:设为草稿 def draft_article(modeladmin, request, queryset): queryset.update(status='d') - +# 批量操作:关闭评论 def close_article_commentstatus(modeladmin, request, queryset): queryset.update(comment_status='c') - +# 批量操作:开启评论 def open_article_commentstatus(modeladmin, request, queryset): queryset.update(comment_status='o') - +# 设置批量操作的显示名称 makr_article_publish.short_description = _('Publish selected articles') draft_article.short_description = _('Draft selected articles') close_article_commentstatus.short_description = _('Close article comments') open_article_commentstatus.short_description = _('Open article comments') + +# 文章模型的管理后台自定义类 class ArticlelAdmin(admin.ModelAdmin): - list_per_page = 20 - search_fields = ('body', 'title') - form = ArticleForm + list_per_page = 20 # 每页显示数量 + search_fields = ('body', 'title') # 支持搜索的字段 + form = ArticleForm # 使用自定义表单 list_display = ( 'id', 'title', @@ -52,12 +60,12 @@ class ArticlelAdmin(admin.ModelAdmin): 'views', 'status', 'type', - 'article_order') - list_display_links = ('id', 'title') - list_filter = ('status', 'type', 'category') - filter_horizontal = ('tags',) - exclude = ('creation_time', 'last_modify_time') - view_on_site = True + 'article_order') # 列表页显示字段 + list_display_links = ('id', 'title') # 可点击进入详情的字段 + list_filter = ('status', 'type', 'category') # 过滤器 + filter_horizontal = ('tags',) # 多对多字段横向筛选 + exclude = ('creation_time', 'last_modify_time') # 编辑页排除字段 + view_on_site = True # 支持“在站点上查看” actions = [ makr_article_publish, draft_article, diff --git a/src/blog/forms.py b/src/blog/forms.py index 715be76..dc82f9e 100644 --- a/src/blog/forms.py +++ b/src/blog/forms.py @@ -1,19 +1,25 @@ + +# 导入相关模块 import logging from django import forms from haystack.forms import SearchForm +# 获取当前模块的日志记录器 logger = logging.getLogger(__name__) + +# 博客搜索表单,继承自Haystack的SearchForm class BlogSearchForm(SearchForm): - querydata = forms.CharField(required=True) + querydata = forms.CharField(required=True) # 搜索关键字字段,必填 def search(self): + # 重写search方法,执行搜索逻辑 datas = super(BlogSearchForm, self).search() if not self.is_valid(): - return self.no_query_found() + return self.no_query_found() # 表单无效时返回空结果 if self.cleaned_data['querydata']: - logger.info(self.cleaned_data['querydata']) - return datas + logger.info(self.cleaned_data['querydata']) # 记录搜索关键字 + return datas # 返回搜索结果 diff --git a/src/blog/models.py b/src/blog/models.py index 083788b..3b2b297 100644 --- a/src/blog/models.py +++ b/src/blog/models.py @@ -1,3 +1,5 @@ + +# 导入相关模块和库 import logging import re from abc import abstractmethod @@ -14,29 +16,36 @@ from uuslug import slugify from djangoblog.utils import cache_decorator, cache 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) - last_modify_time = models.DateTimeField(_('modify time'), default=now) + id = models.AutoField(primary_key=True) # 主键ID + creation_time = models.DateTimeField(_('creation time'), default=now) # 创建时间 + last_modify_time = models.DateTimeField(_('modify time'), default=now) # 最后修改时间 def save(self, *args, **kwargs): + # 如果是更新文章浏览量,只更新views字段 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) else: + # 自动生成slug字段(用于SEO友好的URL) if 'slug' in self.__dict__: slug = getattr( self, 'title') if 'title' in self.__dict__ else getattr( @@ -45,16 +54,18 @@ class BaseModel(models.Model): super().save(*args, **kwargs) def get_full_url(self): + # 获取当前对象的完整URL site = get_current_site().domain url = "https://{site}{path}".format(site=site, path=self.get_absolute_url()) return url class Meta: - abstract = True + abstract = True # 声明为抽象基类,不会生成数据库表 @abstractmethod def get_absolute_url(self): + # 子类需实现,返回对象的绝对URL pass diff --git a/src/blog/urls.py b/src/blog/urls.py index adf2703..db67a64 100644 --- a/src/blog/urls.py +++ b/src/blog/urls.py @@ -3,58 +3,72 @@ from django.views.decorators.cache import cache_page from . import views +# 博客应用路由配置 app_name = "blog" urlpatterns = [ + # 首页 path( r'', views.IndexView.as_view(), name='index'), + # 首页分页 path( r'page//', views.IndexView.as_view(), name='index_page'), + # 文章详情(按日期和ID) path( r'article////.html', views.ArticleDetailView.as_view(), name='detailbyid'), + # 分类详情 path( r'category/.html', views.CategoryDetailView.as_view(), name='category_detail'), + # 分类详情分页 path( r'category//.html', views.CategoryDetailView.as_view(), name='category_detail_page'), + # 作者详情 path( r'author/.html', views.AuthorDetailView.as_view(), name='author_detail'), + # 作者详情分页 path( r'author//.html', views.AuthorDetailView.as_view(), name='author_detail_page'), + # 标签详情 path( r'tag/.html', views.TagDetailView.as_view(), name='tag_detail'), + # 标签详情分页 path( r'tag//.html', views.TagDetailView.as_view(), name='tag_detail_page'), + # 归档页面,缓存一小时 path( 'archives.html', cache_page( 60 * 60)( views.ArchivesView.as_view()), name='archives'), + # 友链页面 path( 'links.html', views.LinkListView.as_view(), name='links'), + # 文件上传接口 path( r'upload', views.fileupload, name='upload'), + # 清理缓存接口 path( r'clean', views.clean_cache_view, diff --git a/src/blog/views.py b/src/blog/views.py index d5dc7ec..41b8690 100644 --- a/src/blog/views.py +++ b/src/blog/views.py @@ -1,3 +1,5 @@ + +# 导入相关模块和库 import logging import os import uuid @@ -21,27 +23,27 @@ from djangoblog.plugin_manage import hooks from djangoblog.plugin_manage.hook_constants import ARTICLE_CONTENT_HOOK_NAME from djangoblog.utils import cache, get_blog_setting, get_sha256 +# 获取当前模块的日志记录器 logger = logging.getLogger(__name__) -class ArticleListView(ListView): - # template_name属性用于指定使用哪个模板进行渲染 - template_name = 'blog/article_index.html' - - # context_object_name属性用于给上下文变量取名(在模板中使用该名字) - context_object_name = 'article_list' - # 页面类型,分类目录或标签列表等 - page_type = '' - paginate_by = settings.PAGINATE_BY - page_kwarg = 'page' - link_type = LinkShowType.L +# 文章列表视图,负责展示文章列表页面 +class ArticleListView(ListView): + template_name = 'blog/article_index.html' # 指定渲染模板 + context_object_name = 'article_list' # 模板变量名 + page_type = '' # 页面类型(如分类、标签等) + paginate_by = settings.PAGINATE_BY # 分页数量 + page_kwarg = 'page' # 分页参数名 + link_type = LinkShowType.L # 友链展示类型 def get_view_cache_key(self): + # 获取视图缓存的key return self.request.get['pages'] @property def page_number(self): + # 获取当前页码 page_kwarg = self.page_kwarg page = self.kwargs.get( page_kwarg) or self.request.GET.get(page_kwarg) or 1 @@ -49,13 +51,13 @@ class ArticleListView(ListView): def get_queryset_cache_key(self): """ - 子类重写.获得queryset的缓存key + 子类需重写:获得queryset的缓存key """ raise NotImplementedError() def get_queryset_data(self): """ - 子类重写.获取queryset的数据 + 子类需重写:获取queryset的数据 """ raise NotImplementedError()