Compare commits
17 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
42d28565c6 | 3 months ago |
|
|
28fe2d2f6d | 4 months ago |
|
|
0585f9ec1f | 4 months ago |
|
|
d54f7d938e | 4 months ago |
|
|
b28b6d9d58 | 4 months ago |
|
|
c9e3827ea8 | 4 months ago |
|
|
8cde1760ad | 4 months ago |
|
|
d4e9488a6f | 4 months ago |
|
|
267d5cb2b4 | 4 months ago |
|
|
9ed7aeec5d | 4 months ago |
|
|
e8bc07545c | 4 months ago |
|
|
0992084222 | 4 months ago |
|
|
b5e33a035b | 4 months ago |
|
|
c76f864233 | 4 months ago |
|
|
3ef0c31a81 | 4 months ago |
|
|
4c0e66471e | 4 months ago |
|
|
926cb41ed3 | 4 months ago |
@ -0,0 +1,52 @@
|
||||
#zr 初始数据库迁移文件:创建评论表结构
|
||||
# Generated by Django 4.1.7 on 2023-03-02 07:14
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
|
||||
#zr 数据库迁移类
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
#zr 初始迁移
|
||||
initial = True
|
||||
|
||||
#zr 依赖关系
|
||||
dependencies = [
|
||||
('blog', '0001_initial'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
#zr 迁移操作
|
||||
operations = [
|
||||
#zr 创建评论表
|
||||
migrations.CreateModel(
|
||||
name='Comment',
|
||||
fields=[
|
||||
#zr 主键ID字段
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
#zr 评论正文字段
|
||||
('body', models.TextField(max_length=300, verbose_name='正文')),
|
||||
#zr 创建时间字段
|
||||
('created_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='创建时间')),
|
||||
#zr 最后修改时间字段
|
||||
('last_mod_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='修改时间')),
|
||||
#zr 是否显示字段
|
||||
('is_enable', models.BooleanField(default=True, verbose_name='是否显示')),
|
||||
#zr 文章外键关联
|
||||
('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='blog.article', verbose_name='文章')),
|
||||
#zr 作者外键关联
|
||||
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='作者')),
|
||||
#zr 父评论自关联
|
||||
('parent_comment', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='comments.comment', verbose_name='上级评论')),
|
||||
],
|
||||
#zr 模型元选项
|
||||
options={
|
||||
'verbose_name': '评论',
|
||||
'verbose_name_plural': '评论',
|
||||
'ordering': ['-id'],
|
||||
'get_latest_by': 'id',
|
||||
},
|
||||
),
|
||||
]
|
||||
@ -0,0 +1,73 @@
|
||||
#zr 数据库迁移文件:更新评论模型字段和选项
|
||||
# Generated by Django 4.2.5 on 2023-09-06 13:13
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
|
||||
#zr 数据库迁移类
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
#zr 依赖的迁移文件
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('blog', '0005_alter_article_options_alter_category_options_and_more'),
|
||||
('comments', '0002_alter_comment_is_enable'),
|
||||
]
|
||||
|
||||
#zr 迁移操作列表
|
||||
operations = [
|
||||
#zr 更新评论模型的元选项
|
||||
migrations.AlterModelOptions(
|
||||
name='comment',
|
||||
options={'get_latest_by': 'id', 'ordering': ['-id'], 'verbose_name': 'comment', 'verbose_name_plural': 'comment'},
|
||||
),
|
||||
#zr 移除旧的创建时间字段
|
||||
migrations.RemoveField(
|
||||
model_name='comment',
|
||||
name='created_time',
|
||||
),
|
||||
#zr 移除旧的最后修改时间字段
|
||||
migrations.RemoveField(
|
||||
model_name='comment',
|
||||
name='last_mod_time',
|
||||
),
|
||||
#zr 添加新的创建时间字段
|
||||
migrations.AddField(
|
||||
model_name='comment',
|
||||
name='creation_time',
|
||||
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time'),
|
||||
),
|
||||
#zr 添加新的最后修改时间字段
|
||||
migrations.AddField(
|
||||
model_name='comment',
|
||||
name='last_modify_time',
|
||||
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='last modify time'),
|
||||
),
|
||||
#zr 更新文章外键字段配置
|
||||
migrations.AlterField(
|
||||
model_name='comment',
|
||||
name='article',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='blog.article', verbose_name='article'),
|
||||
),
|
||||
#zr 更新作者外键字段配置
|
||||
migrations.AlterField(
|
||||
model_name='comment',
|
||||
name='author',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='author'),
|
||||
),
|
||||
#zr 更新是否启用字段配置
|
||||
migrations.AlterField(
|
||||
model_name='comment',
|
||||
name='is_enable',
|
||||
field=models.BooleanField(default=False, verbose_name='enable'),
|
||||
),
|
||||
#zr 更新父评论外键字段配置
|
||||
migrations.AlterField(
|
||||
model_name='comment',
|
||||
name='parent_comment',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='comments.comment', verbose_name='parent comment'),
|
||||
),
|
||||
]
|
||||
|
||||
@ -0,0 +1,56 @@
|
||||
from django.contrib import admin
|
||||
from django.urls import reverse
|
||||
from django.utils.html import format_html
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
#zr 禁用评论状态的管理动作
|
||||
def disable_commentstatus(modeladmin, request, queryset):
|
||||
queryset.update(is_enable=False)
|
||||
|
||||
#zr 启用评论状态的管理动作
|
||||
def enable_commentstatus(modeladmin, request, queryset):
|
||||
queryset.update(is_enable=True)
|
||||
|
||||
#zr 设置动作的描述信息
|
||||
disable_commentstatus.short_description = _('Disable comments')
|
||||
enable_commentstatus.short_description = _('Enable comments')
|
||||
|
||||
#zr 评论管理后台配置类
|
||||
class CommentAdmin(admin.ModelAdmin):
|
||||
#zr 设置每页显示数量
|
||||
list_per_page = 20
|
||||
#zr 设置列表页显示的字段
|
||||
list_display = (
|
||||
'id',
|
||||
'body',
|
||||
'link_to_userinfo',
|
||||
'link_to_article',
|
||||
'is_enable',
|
||||
'creation_time')
|
||||
#zr 设置可点击链接的字段
|
||||
list_display_links = ('id', 'body', 'is_enable')
|
||||
#zr 设置过滤器字段
|
||||
list_filter = ('is_enable',)
|
||||
#zr 设置排除的表单字段
|
||||
exclude = ('creation_time', 'last_modify_time')
|
||||
#zr 设置可用的批量动作
|
||||
actions = [disable_commentstatus, enable_commentstatus]
|
||||
|
||||
#zr 生成用户信息链接的方法
|
||||
def link_to_userinfo(self, obj):
|
||||
info = (obj.author._meta.app_label, obj.author._meta.model_name)
|
||||
link = reverse('admin:%s_%s_change' % info, args=(obj.author.id,))
|
||||
return format_html(
|
||||
u'<a href="%s">%s</a>' %
|
||||
(link, obj.author.nickname if obj.author.nickname else obj.author.email))
|
||||
|
||||
#zr 生成文章链接的方法
|
||||
def link_to_article(self, obj):
|
||||
info = (obj.article._meta.app_label, obj.article._meta.model_name)
|
||||
link = reverse('admin:%s_%s_change' % info, args=(obj.article.id,))
|
||||
return format_html(
|
||||
u'<a href="%s">%s</a>' % (link, obj.article.title))
|
||||
|
||||
#zr 设置自定义字段的显示名称
|
||||
link_to_userinfo.short_description = _('User')
|
||||
link_to_article.short_description = _('Article')
|
||||
@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
#zr 评论应用配置类
|
||||
class CommentsConfig(AppConfig):
|
||||
#zr 定义应用名称
|
||||
name = 'comments'
|
||||
@ -0,0 +1,37 @@
|
||||
from django import template
|
||||
|
||||
#zr 注册模板标签库
|
||||
register = template.Library()
|
||||
|
||||
#zr 解析评论树的模板标签
|
||||
@register.simple_tag
|
||||
def parse_commenttree(commentlist, comment):
|
||||
"""获得当前评论子评论的列表
|
||||
用法: {% parse_commenttree article_comments comment as childcomments %}
|
||||
"""
|
||||
datas = []
|
||||
|
||||
#zr 递归解析子评论的内部函数
|
||||
def parse(c):
|
||||
#zr 获取当前评论的直接子评论
|
||||
childs = commentlist.filter(parent_comment=c, is_enable=True)
|
||||
for child in childs:
|
||||
#zr 将子评论添加到结果列表
|
||||
datas.append(child)
|
||||
#zr 递归解析子评论的子评论
|
||||
parse(child)
|
||||
|
||||
#zr 从传入的评论开始解析
|
||||
parse(comment)
|
||||
return datas
|
||||
|
||||
#zr 显示评论项的包含标签
|
||||
@register.inclusion_tag('comments/tags/comment_item.html')
|
||||
def show_comment_item(comment, ischild):
|
||||
"""评论"""
|
||||
#zr 根据是否为子评论设置不同的深度
|
||||
depth = 1 if ischild else 2
|
||||
return {
|
||||
'comment_item': comment,
|
||||
'depth': depth
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
#zr 定义评论应用的命名空间
|
||||
app_name = "comments"
|
||||
#zr 评论模块URL路由配置
|
||||
urlpatterns = [
|
||||
#zr 文章评论提交路由
|
||||
path(
|
||||
'article/<int:article_id>/postcomment',
|
||||
views.CommentPostView.as_view(),
|
||||
name='postcomment'),
|
||||
]
|
||||
@ -0,0 +1,50 @@
|
||||
import logging
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from djangoblog.utils import get_current_site
|
||||
from djangoblog.utils import send_email
|
||||
|
||||
# zr 获取当前模块的日志记录器
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# zr 发送评论邮件功能
|
||||
def send_comment_email(comment):
|
||||
# zr 获取当前站点域名
|
||||
site = get_current_site().domain
|
||||
# zr 设置邮件主题
|
||||
subject = _('Thanks for your comment')
|
||||
# zr 构建文章完整URL
|
||||
article_url = f"https://{site}{comment.article.get_absolute_url()}"
|
||||
# zr 构建给评论作者的邮件内容
|
||||
html_content = _("""<p>Thank you very much for your comments on this site</p>
|
||||
You can visit <a href="%(article_url)s" rel="bookmark">%(article_title)s</a>
|
||||
to review your comments,
|
||||
Thank you again!
|
||||
<br />
|
||||
If the link above cannot be opened, please copy this link to your browser.
|
||||
%(article_url)s""") % {'article_url': article_url, 'article_title': comment.article.title}
|
||||
# zr 获取评论作者邮箱并发送邮件
|
||||
tomail = comment.author.email
|
||||
send_email([tomail], subject, html_content)
|
||||
|
||||
# zr 如果是回复评论,同时发送邮件给被回复的评论作者
|
||||
try:
|
||||
if comment.parent_comment:
|
||||
# zr 构建回复通知邮件内容
|
||||
html_content = _("""Your comment on <a href="%(article_url)s" rel="bookmark">%(article_title)s</a><br/> has
|
||||
received a reply. <br/> %(comment_body)s
|
||||
<br/>
|
||||
go check it out!
|
||||
<br/>
|
||||
If the link above cannot be opened, please copy this link to your browser.
|
||||
%(article_url)s
|
||||
""") % {'article_url': article_url, 'article_title': comment.article.title,
|
||||
'comment_body': comment.parent_comment.body}
|
||||
# zr 获取被回复评论作者的邮箱并发送通知
|
||||
tomail = comment.parent_comment.author.email
|
||||
send_email([tomail], subject, html_content)
|
||||
except Exception as e:
|
||||
# zr 记录邮件发送异常
|
||||
logger.error(e)
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue