From ce347eff5eedad3cf0f770ab1ef1b1b7da3f1655 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=95=86=E4=B8=96=E6=B5=9A?= <2461457601@qq.com> Date: Sun, 2 Nov 2025 20:06:22 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84comment=E5=8C=85=E4=B8=8B?= =?UTF-8?q?=E7=9A=84=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/djangoBlogStudy.iml | 2 +- src/comments/admin.py | 6 ++++++ src/comments/apps.py | 2 +- src/comments/forms.py | 3 ++- src/comments/migrations/0001_initial.py | 3 ++- .../migrations/0002_alter_comment_is_enable.py | 3 +++ ...ions_remove_comment_created_time_and_more.py | 3 ++- src/comments/models.py | 5 ++++- src/comments/tests.py | 17 ++++++++++------- src/comments/urls.py | 1 + src/comments/utils.py | 7 +++++-- src/comments/views.py | 14 +++++++++++--- 12 files changed, 48 insertions(+), 18 deletions(-) diff --git a/.idea/djangoBlogStudy.iml b/.idea/djangoBlogStudy.iml index e378968..850ee37 100644 --- a/.idea/djangoBlogStudy.iml +++ b/.idea/djangoBlogStudy.iml @@ -2,7 +2,7 @@ - + diff --git a/src/comments/admin.py b/src/comments/admin.py index 8a5afc6..8021a33 100644 --- a/src/comments/admin.py +++ b/src/comments/admin.py @@ -11,6 +11,7 @@ from django.utils.html import format_html from django.utils.translation import gettext_lazy as _ +#ssj # 自定义管理员操作:批量禁用选中的评论 def disable_commentstatus(modeladmin, request, queryset): """ @@ -21,6 +22,7 @@ def disable_commentstatus(modeladmin, request, queryset): queryset.update(is_enable=False) +#ssj # 自定义管理员操作:批量启用选中的评论 def enable_commentstatus(modeladmin, request, queryset): """ @@ -31,11 +33,13 @@ def enable_commentstatus(modeladmin, request, queryset): queryset.update(is_enable=True) +#ssj # 为自定义操作设置在管理界面中显示的描述文本(支持国际化) disable_commentstatus.short_description = _('Disable comments') # 显示为“禁用评论” enable_commentstatus.short_description = _('Enable comments') # 显示为“启用评论” +#ssj # 定义 Comment 模型在 Django 管理后台的显示和操作配置 class CommentAdmin(admin.ModelAdmin): # 设置评论列表每页显示 20 条数据 @@ -64,6 +68,7 @@ class CommentAdmin(admin.ModelAdmin): # 注册自定义的批量操作,允许管理员在列表页选择多条评论执行“启用”或“禁用” actions = [disable_commentstatus, enable_commentstatus] +#ssj def link_to_userinfo(self, obj): """ 自定义列表字段:生成指向评论作者用户信息编辑页面的超链接 @@ -83,6 +88,7 @@ class CommentAdmin(admin.ModelAdmin): u'%s' % (link, obj.author.nickname if obj.author.nickname else obj.author.email)) +#ssj def link_to_article(self, obj): """ 自定义列表字段:生成指向评论所属文章编辑页面的超链接 diff --git a/src/comments/apps.py b/src/comments/apps.py index 96d8d00..9bd0622 100644 --- a/src/comments/apps.py +++ b/src/comments/apps.py @@ -1,7 +1,7 @@ # 导入 Django 应用配置基类 from django.apps import AppConfig - +#ssj # 定义 comments 应用的配置类 class CommentsConfig(AppConfig): # 指定该配置对应的 Django 应用的完整 Python 路径 diff --git a/src/comments/forms.py b/src/comments/forms.py index dcc6088..2b8af47 100644 --- a/src/comments/forms.py +++ b/src/comments/forms.py @@ -3,7 +3,7 @@ from django.forms import ModelForm from .models import Comment - +#ssj # 定义一个用于处理评论数据的表单类,继承自 Django 的 ModelForm class CommentForm(ModelForm): # 自定义字段:parent_comment_id @@ -13,6 +13,7 @@ class CommentForm(ModelForm): required=False # 非必填字段,因为一级评论没有父评论 ) +#ssj class Meta: model = Comment # 关联的数据库模型为 Comment fields = ['body'] # 表单中需要包含的模型字段,仅包含 'body'(评论正文) diff --git a/src/comments/migrations/0001_initial.py b/src/comments/migrations/0001_initial.py index 9c4f9a1..e330305 100644 --- a/src/comments/migrations/0001_initial.py +++ b/src/comments/migrations/0001_initial.py @@ -1,9 +1,10 @@ +#ssj from django.conf import settings from django.db import migrations, models import django.db.models.deletion import django.utils.timezone - +#ssj class Migration(migrations.Migration): # 表示这是一个初始迁移(即创建模型的第一次迁移) initial = True diff --git a/src/comments/migrations/0002_alter_comment_is_enable.py b/src/comments/migrations/0002_alter_comment_is_enable.py index d0511f1..df05a28 100644 --- a/src/comments/migrations/0002_alter_comment_is_enable.py +++ b/src/comments/migrations/0002_alter_comment_is_enable.py @@ -1,7 +1,9 @@ +#ssj from django.db import migrations, models # migrations: 用于定义数据库迁移操作 # models: 用于定义模型字段类型 +#ssj class Migration(migrations.Migration): # 定义一个迁移类,继承自 django.db.migrations.Migration @@ -13,6 +15,7 @@ class Migration(migrations.Migration): # 之后才能执行当前迁移 +#ssj operations = [ # 定义本次迁移要执行的数据库操作列表 migrations.AlterField( # 执行一个“修改字段”的操作 model_name='comment', # 要修改的模型名称(对应 comments 应用中的 Comment 模型) diff --git a/src/comments/migrations/0003_alter_comment_options_remove_comment_created_time_and_more.py b/src/comments/migrations/0003_alter_comment_options_remove_comment_created_time_and_more.py index c07de08..8d42e73 100644 --- a/src/comments/migrations/0003_alter_comment_options_remove_comment_created_time_and_more.py +++ b/src/comments/migrations/0003_alter_comment_options_remove_comment_created_time_and_more.py @@ -5,7 +5,7 @@ from django.db import migrations, models import django.db.models.deletion import django.utils.timezone # 用于引用 AUTH_USER_MODEL - +#ssj class Migration(migrations.Migration): dependencies = [ # 当前迁移所依赖的其他迁移,必须按顺序执行完这些依赖迁移后,才能执行本迁移 @@ -14,6 +14,7 @@ class Migration(migrations.Migration): ('comments', '0002_alter_comment_is_enable'), # 依赖于 comments 应用的第 2 个迁移(之前已修改过 is_enable 字段的默认值) ] +#ssj operations = [ # 定义本次迁移要执行的所有数据库操作 # 1. 修改模型的元选项(Meta options) migrations.AlterModelOptions( diff --git a/src/comments/models.py b/src/comments/models.py index 1baae24..ff59af9 100644 --- a/src/comments/models.py +++ b/src/comments/models.py @@ -3,9 +3,10 @@ from django.db import models from django.utils.timezone import now from django.utils.translation import gettext_lazy as _ -from blog.models import Article +from ..blog.models import Article +#ssj # 定义评论模型,用于存储用户对文章的评论数据 class Comment(models.Model): # 评论正文内容 @@ -58,6 +59,7 @@ class Comment(models.Model): is_enable = models.BooleanField(_('enable'), default=False, blank=False, null=False) +#ssj class Meta: """ 模型元数据类:定义模型的元信息,如排序、名称等 @@ -74,6 +76,7 @@ class Comment(models.Model): # 指定获取最新一条记录时依据的字段 get_latest_by = 'id' +#ssj def __str__(self): """ 返回该评论对象的字符串表示 diff --git a/src/comments/tests.py b/src/comments/tests.py index 3110226..1ca8c86 100644 --- a/src/comments/tests.py +++ b/src/comments/tests.py @@ -1,15 +1,16 @@ from django.test import Client, RequestFactory, TransactionTestCase from django.urls import reverse -from accounts.models import BlogUser -from blog.models import Category, Article -from comments.models import Comment -from comments.templatetags.comments_tags import * -from djangoblog.utils import get_max_articleid_commentid +from ..accounts.models import BlogUser +from ..blog.models import Category, Article +from ..comments.models import Comment +from ..comments.templatetags.comments_tags import * +from ..djangoblog.utils import get_max_articleid_commentid # Create your tests here. +#ssj # 定义一个基于事务的测试用例类,用于测试 comments 应用的相关功能 class CommentsTest(TransactionTestCase): def setUp(self): @@ -20,7 +21,7 @@ class CommentsTest(TransactionTestCase): self.factory = RequestFactory() # 导入博客设置模型(由于导入在方法内,可能为了延迟加载或避免循环导入) - from blog.models import BlogSettings + from ..blog.models import BlogSettings # 创建一个博客全局设置实例 value = BlogSettings() @@ -35,6 +36,7 @@ class CommentsTest(TransactionTestCase): username="liangliangyy1", password="liangliangyy1") +#ssj def update_article_comment_status(self, article): # 获取该文章的所有评论 comments = article.comment_set.all() @@ -42,6 +44,7 @@ class CommentsTest(TransactionTestCase): comment.is_enable = True # 启用评论 comment.save() # 保存更改 +#ssj def test_validate_comment(self): # 使用测试用户登录(确保有权限发表评论) self.client.login(username='liangliangyy1', password='liangliangyy1') @@ -147,6 +150,6 @@ class CommentsTest(TransactionTestCase): self.assertIsNotNone(s) # 从 utils 模块导入发送评论邮件函数 - from comments.utils import send_comment_email + from ..comments.utils import send_comment_email # 测试发送评论通知邮件功能 send_comment_email(comment) \ No newline at end of file diff --git a/src/comments/urls.py b/src/comments/urls.py index 2cc8624..72cc92d 100644 --- a/src/comments/urls.py +++ b/src/comments/urls.py @@ -6,6 +6,7 @@ from . import views # 在项目其他地方可以通过 'comments:xxx' 的方式反向解析 URL app_name = "comments" +#ssj # 定义 comments 应用的 URL 路由列表 urlpatterns = [ # 路由配置:将特定 URL 模式映射到对应的视图处理逻辑 diff --git a/src/comments/utils.py b/src/comments/utils.py index f42e6cb..053e5ac 100644 --- a/src/comments/utils.py +++ b/src/comments/utils.py @@ -2,13 +2,14 @@ import logging from django.utils.translation import gettext_lazy as _ -from djangoblog.utils import get_current_site -from djangoblog.utils import send_email +from ..djangoblog.utils import get_current_site +from ..djangoblog.utils import send_email # 获取当前模块的 logger 实例,用于记录日志 logger = logging.getLogger(__name__) +#ssj def send_comment_email(comment): # 获取当前站点的域名(如 example.com) site = get_current_site().domain @@ -38,6 +39,7 @@ def send_comment_email(comment): # 调用发送邮件的通用函数,发送感谢邮件 send_email([tomail], subject, html_content) +#ssj try: # 如果当前评论是回复(即存在父评论) if comment.parent_comment: @@ -62,6 +64,7 @@ def send_comment_email(comment): # 发送回复通知邮件 send_email([tomail], subject, html_content) +#ssj except Exception as e: # 如果在发送通知邮件过程中发生异常(如用户无邮箱等),记录错误日志 logger.error(e) \ No newline at end of file diff --git a/src/comments/views.py b/src/comments/views.py index 465d23e..562426f 100644 --- a/src/comments/views.py +++ b/src/comments/views.py @@ -6,12 +6,13 @@ from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_protect from django.views.generic.edit import FormView -from accounts.models import BlogUser -from blog.models import Article +from ..accounts.models import BlogUser +from ..blog.models import Article from .forms import CommentForm from .models import Comment +#ssj # 定义一个基于类的视图,用于处理用户提交评论的请求 class CommentPostView(FormView): # 指定该视图使用的表单类 @@ -20,10 +21,12 @@ class CommentPostView(FormView): # 指定表单验证失败时,或需要渲染响应时使用的模板 template_name = 'blog/article_detail.html' +#ssj @method_decorator(csrf_protect) def dispatch(self, *args, **kwargs): return super(CommentPostView, self).dispatch(*args, **kwargs) +#ssj def get(self, request, *args, **kwargs): # 从 URL 参数中获取文章 ID article_id = self.kwargs['article_id'] @@ -37,6 +40,7 @@ class CommentPostView(FormView): # 重定向到文章页面,并锚定到 id="comments" 的元素(通常是评论列表) return HttpResponseRedirect(url + "#comments") +#ssj def form_invalid(self, form): # 获取文章 ID article_id = self.kwargs['article_id'] @@ -50,6 +54,7 @@ class CommentPostView(FormView): 'article': article }) +#ssj def form_valid(self, form): """提交的数据验证合法后的逻辑""" @@ -65,6 +70,7 @@ class CommentPostView(FormView): # 获取对应的文章对象(404 安全获取) article = get_object_or_404(Article, pk=article_id) +#ssj # 检查文章是否允许评论 # 如果文章的评论状态为 'c'(关闭)或文章状态为 'c'(草稿等),则禁止评论 if article.comment_status == 'c' or article.status == 'c': @@ -78,7 +84,7 @@ class CommentPostView(FormView): comment.article = article # 导入博客设置工具函数 - from djangoblog.utils import get_blog_setting + from ..djangoblog.utils import get_blog_setting # 获取当前博客的全局设置 settings = get_blog_setting() @@ -90,6 +96,7 @@ class CommentPostView(FormView): # 设置评论作者 comment.author = author +#ssj # 检查表单中是否包含父评论 ID(即是否为回复) if form.cleaned_data['parent_comment_id']: # 根据父评论 ID 获取父评论对象 @@ -101,6 +108,7 @@ class CommentPostView(FormView): # 将评论对象保存到数据库(此时所有字段已设置完毕) comment.save(True) +#ssj # 重定向到文章详情页,并定位到刚刚发表的评论 # 使用锚点 #div-comment-{id} 定位到具体评论 return HttpResponseRedirect(