|
|
from django.shortcuts import render, get_object_or_404, redirect
|
|
|
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
|
|
from django.db.models import Q
|
|
|
from django.contrib import messages
|
|
|
from django.contrib.auth.decorators import login_required
|
|
|
from django.http import JsonResponse
|
|
|
from django.views.decorators.http import require_POST
|
|
|
from .models import Post, Category
|
|
|
from .forms import PostForm
|
|
|
from comments.forms import CommentForm # 从comments应用导入CommentForm
|
|
|
|
|
|
def index(request):
|
|
|
"""首页视图 - 显示最新发布的文章"""
|
|
|
# LXC:获取所有已发布的文章,按照创建时间倒序排列
|
|
|
post_list_all = Post.objects.filter(status='published').order_by('-created_time')
|
|
|
|
|
|
# LXC:创建分页器对象,每页显示10篇文章
|
|
|
paginator = Paginator(post_list_all, 10)
|
|
|
page_number = request.GET.get('page')
|
|
|
|
|
|
try:
|
|
|
post_list = paginator.page(page_number)
|
|
|
except PageNotAnInteger:
|
|
|
# LXC:当页码不是整数时,显示第一页内容
|
|
|
post_list = paginator.page(1)
|
|
|
except EmptyPage:
|
|
|
# LXC:当页码超出范围时,显示最后一页内容
|
|
|
post_list = paginator.page(paginator.num_pages)
|
|
|
|
|
|
# LXC:获取热门文章,按浏览量降序排列,取前5篇
|
|
|
hot_posts = Post.objects.filter(status='published').order_by('-views')[:5]
|
|
|
|
|
|
# LXC:构建页面上下文数据
|
|
|
context = {
|
|
|
'post_list': post_list,
|
|
|
'hot_posts': hot_posts,
|
|
|
'category_info': {
|
|
|
'name': '非遗传承',
|
|
|
'label': '',
|
|
|
'desc': '探索南京非物质文化遗产的独特魅力与传承故事'
|
|
|
},
|
|
|
'current_path': request.path,
|
|
|
'current_category_id': None
|
|
|
}
|
|
|
|
|
|
# LXC:渲染首页模板并返回响应
|
|
|
return render(request, 'blog/index.html', context)
|
|
|
|
|
|
def category_view(request, category_id):
|
|
|
"""分类页面视图 - 显示指定分类的文章"""
|
|
|
# LXC:根据分类ID获取分类对象,如果不存在则返回404错误
|
|
|
category = get_object_or_404(Category, id=category_id)
|
|
|
|
|
|
# LXC:获取该分类下所有已发布的文章,按创建时间倒序排列
|
|
|
posts_all = Post.objects.filter(category=category, status='published').order_by('-created_time')
|
|
|
|
|
|
# LXC:创建分页器对象,每页显示10篇文章
|
|
|
paginator = Paginator(posts_all, 10)
|
|
|
page_number = request.GET.get('page')
|
|
|
|
|
|
try:
|
|
|
posts = paginator.page(page_number)
|
|
|
except PageNotAnInteger:
|
|
|
posts = paginator.page(1)
|
|
|
except EmptyPage:
|
|
|
posts = paginator.page(paginator.num_pages)
|
|
|
|
|
|
# LXC:获取热门文章,按浏览量降序排列,取前5篇
|
|
|
hot_posts = Post.objects.filter(status='published').order_by('-views')[:5]
|
|
|
|
|
|
# LXC:定义分类信息映射字典,包含每个分类的显示标签和描述
|
|
|
category_map = {
|
|
|
1: {'label': '巧夺天工·工艺', 'desc': '探索南京传统手工艺的精湛技艺与匠心传承'},
|
|
|
2: {'label': '梨园雅韵·表演', 'desc': '感受南京传统表演艺术的独特韵味与舞台魅力'},
|
|
|
3: {'label': '人间烟火·民俗', 'desc': '体验南京丰富多彩的民俗活动与民间传统'},
|
|
|
4: {'label': '口传心授·文学', 'desc': '领略南京口传文学的语言艺术与文化内涵'},
|
|
|
5: {'label': '匠心传承·人物', 'desc': '认识南京非物质文化遗产的传承人与守护者'},
|
|
|
}
|
|
|
|
|
|
# LXC:根据分类ID获取对应的分类信息,如果不存在则使用默认值
|
|
|
category_info = category_map.get(category_id, {
|
|
|
'label': category.name,
|
|
|
'desc': f'探索南京{category.name}的独特魅力'
|
|
|
})
|
|
|
|
|
|
# LXC:构建页面上下文数据
|
|
|
context = {
|
|
|
'post_list': posts,
|
|
|
'hot_posts': hot_posts,
|
|
|
'category_info': {
|
|
|
'name': category.name,
|
|
|
'label': category_info['label'],
|
|
|
'desc': category_info['desc']
|
|
|
},
|
|
|
'current_path': request.path,
|
|
|
'current_category_id': category_id
|
|
|
}
|
|
|
|
|
|
# LXC:渲染分类页面模板并返回响应
|
|
|
return render(request, 'blog/index.html', context)
|
|
|
|
|
|
def detail(request, post_id):
|
|
|
"""文章详情页 - 显示单篇文章的完整内容"""
|
|
|
# LXC:根据文章ID获取已发布的文章对象,如果不存在则返回404错误
|
|
|
post = get_object_or_404(Post, id=post_id, status='published')
|
|
|
|
|
|
# LXC:增加文章浏览量并保存到数据库
|
|
|
post.views += 1
|
|
|
post.save()
|
|
|
|
|
|
# LXC:导入评论模型
|
|
|
from comments.models import Comment
|
|
|
|
|
|
# LXC:获取该文章的所有评论,按创建时间倒序排列
|
|
|
comments = post.comments.all().order_by('-created_time')
|
|
|
|
|
|
# LXC:创建评论表单实例
|
|
|
comment_form = CommentForm()
|
|
|
|
|
|
# LXC:构建页面上下文数据
|
|
|
context = {
|
|
|
'post': post,
|
|
|
'comments': comments,
|
|
|
'comment_form': comment_form,
|
|
|
}
|
|
|
|
|
|
# LXC:渲染文章详情页模板并返回响应
|
|
|
return render(request, 'blog/detail.html', context)
|
|
|
|
|
|
def search(request):
|
|
|
"""搜索文章 - 根据关键词搜索文章内容"""
|
|
|
# LXC:获取搜索关键词并去除首尾空格
|
|
|
query = request.GET.get('q', '').strip()
|
|
|
|
|
|
# LXC:获取热门文章,按浏览量降序排列,取前5篇
|
|
|
hot_posts = Post.objects.filter(status='published').order_by('-views')[:5]
|
|
|
|
|
|
# LXC:初始化空的搜索结果集
|
|
|
results = Post.objects.none()
|
|
|
result_count = 0
|
|
|
|
|
|
if query:
|
|
|
# LXC:如果有关键词,执行多字段搜索
|
|
|
results = Post.objects.filter(
|
|
|
Q(title__icontains=query) |
|
|
|
Q(content__icontains=query) |
|
|
|
Q(excerpt__icontains=query) |
|
|
|
Q(primary_tags__name__icontains=query) |
|
|
|
Q(secondary_tags__name__icontains=query),
|
|
|
status='published'
|
|
|
).distinct().order_by('-created_time')
|
|
|
|
|
|
# LXC:统计搜索结果数量
|
|
|
result_count = results.count()
|
|
|
|
|
|
# LXC:如果没有搜索结果,添加提示消息
|
|
|
if result_count == 0:
|
|
|
messages.info(request, f'没有找到包含"{query}"的文章,请尝试其他关键词。')
|
|
|
else:
|
|
|
# LXC:如果没有输入关键词,显示提示信息
|
|
|
messages.info(request, '请输入搜索关键词。')
|
|
|
|
|
|
# LXC:创建分页器对象,每页显示10篇文章
|
|
|
paginator = Paginator(results, 10)
|
|
|
page_number = request.GET.get('page')
|
|
|
|
|
|
try:
|
|
|
page_obj = paginator.page(page_number)
|
|
|
except PageNotAnInteger:
|
|
|
page_obj = paginator.page(1)
|
|
|
except EmptyPage:
|
|
|
page_obj = paginator.page(paginator.num_pages)
|
|
|
|
|
|
# LXC:构建页面上下文数据
|
|
|
context = {
|
|
|
'post_list': page_obj,
|
|
|
'hot_posts': hot_posts,
|
|
|
'category_info': {
|
|
|
'name': f'搜索"{query}"' if query else '搜索',
|
|
|
'label': '搜索结果',
|
|
|
'desc': f'找到 {result_count} 篇相关文章' if query else '请输入搜索关键词'
|
|
|
},
|
|
|
'current_path': request.path,
|
|
|
'current_category_id': None,
|
|
|
'search_query': query
|
|
|
}
|
|
|
|
|
|
return render(request, 'blog/index.html', context)
|
|
|
|
|
|
def about(request):
|
|
|
"""关于页面 - 网站介绍"""
|
|
|
context = {
|
|
|
'category_info': {
|
|
|
'name': '关于我们',
|
|
|
'label': '关于金陵非遗',
|
|
|
'desc': '了解南京非物质文化遗产保护与传承的使命'
|
|
|
},
|
|
|
'current_path': request.path,
|
|
|
}
|
|
|
return render(request, 'blog/about.html', context)
|
|
|
|
|
|
# ========== 文章管理视图函数 ==========
|
|
|
|
|
|
@login_required
|
|
|
def create_post(request):
|
|
|
"""发表新文章"""
|
|
|
if request.method == 'POST':
|
|
|
# LXC:使用POST数据和文件数据初始化表单
|
|
|
form = PostForm(request.POST, request.FILES)
|
|
|
if form.is_valid():
|
|
|
# LXC:保存文章但不提交到数据库,以便设置作者
|
|
|
post = form.save(commit=False)
|
|
|
# LXC:设置文章作者为当前登录用户
|
|
|
post.author = request.user
|
|
|
# LXC:新文章默认为草稿状态
|
|
|
post.status = 'draft'
|
|
|
post.save()
|
|
|
|
|
|
# LXC:保存多对多关系(标签)
|
|
|
form.save_m2m()
|
|
|
|
|
|
messages.success(request, '文章创建成功!已保存为草稿。')
|
|
|
return redirect('user_posts')
|
|
|
else:
|
|
|
messages.error(request, '文章创建失败,请检查表单内容。')
|
|
|
else:
|
|
|
# LXC:GET请求时创建空表单
|
|
|
form = PostForm()
|
|
|
|
|
|
context = {
|
|
|
'form': form,
|
|
|
'category_info': {
|
|
|
'name': '发表文章',
|
|
|
'label': '创作非遗',
|
|
|
'desc': '分享您对南京非物质文化遗产的见解和故事'
|
|
|
},
|
|
|
'current_path': request.path,
|
|
|
}
|
|
|
return render(request, 'blog/create_post.html', context)
|
|
|
|
|
|
@login_required
|
|
|
def user_posts(request):
|
|
|
"""用户个人文章管理"""
|
|
|
# LXC:获取当前用户的所有文章,按创建时间倒序排列
|
|
|
posts = Post.objects.filter(author=request.user).order_by('-created_time')
|
|
|
|
|
|
context = {
|
|
|
'posts': posts,
|
|
|
'category_info': {
|
|
|
'name': '我的文章',
|
|
|
'label': '个人创作',
|
|
|
'desc': '管理您发表的非遗文章'
|
|
|
},
|
|
|
'current_path': request.path,
|
|
|
}
|
|
|
return render(request, 'blog/user_posts.html', context)
|
|
|
|
|
|
@login_required
|
|
|
def edit_post(request, post_id):
|
|
|
"""编辑文章"""
|
|
|
# LXC:获取文章对象,确保作者是当前用户
|
|
|
post = get_object_or_404(Post, id=post_id, author=request.user)
|
|
|
|
|
|
if request.method == 'POST':
|
|
|
# LXC:使用POST数据和文件数据初始化表单,并绑定到现有文章实例
|
|
|
form = PostForm(request.POST, request.FILES, instance=post)
|
|
|
if form.is_valid():
|
|
|
form.save()
|
|
|
messages.success(request, '文章更新成功!')
|
|
|
return redirect('user_posts')
|
|
|
else:
|
|
|
messages.error(request, '文章更新失败,请检查表单内容。')
|
|
|
else:
|
|
|
# LXC:GET请求时使用现有文章数据初始化表单
|
|
|
form = PostForm(instance=post)
|
|
|
|
|
|
context = {
|
|
|
'form': form,
|
|
|
'post': post,
|
|
|
'category_info': {
|
|
|
'name': '编辑文章',
|
|
|
'label': '修改创作',
|
|
|
'desc': '修改您的非遗文章内容'
|
|
|
},
|
|
|
'current_path': request.path,
|
|
|
}
|
|
|
return render(request, 'blog/edit_post.html', context)
|
|
|
|
|
|
@login_required
|
|
|
@require_POST
|
|
|
def publish_post(request, post_id):
|
|
|
"""发布文章(将草稿状态改为已发布)"""
|
|
|
# LXC:获取文章对象,确保作者是当前用户
|
|
|
post = get_object_or_404(Post, id=post_id, author=request.user)
|
|
|
|
|
|
if post.status == 'draft':
|
|
|
# LXC:将文章状态从草稿改为已发布
|
|
|
post.status = 'published'
|
|
|
post.save()
|
|
|
messages.success(request, '文章已成功发布!')
|
|
|
else:
|
|
|
messages.warning(request, '文章状态未改变。')
|
|
|
|
|
|
return redirect('user_posts')
|
|
|
|
|
|
@login_required
|
|
|
@require_POST
|
|
|
def delete_post(request, post_id):
|
|
|
"""删除文章"""
|
|
|
# LXC:获取文章对象,确保作者是当前用户
|
|
|
post = get_object_or_404(Post, id=post_id, author=request.user)
|
|
|
post_title = post.title
|
|
|
# LXC:删除文章
|
|
|
post.delete()
|
|
|
|
|
|
messages.success(request, f'文章 "{post_title}" 已删除。')
|
|
|
return redirect('user_posts')
|
|
|
|
|
|
@login_required
|
|
|
@require_POST
|
|
|
def like_post(request, post_id):
|
|
|
"""点赞文章"""
|
|
|
# LXC:获取文章对象
|
|
|
post = get_object_or_404(Post, id=post_id)
|
|
|
|
|
|
# LXC:实现点赞功能逻辑
|
|
|
if post.likes.filter(id=request.user.id).exists():
|
|
|
# LXC:如果已经点赞,取消点赞
|
|
|
post.likes.remove(request.user)
|
|
|
liked = False
|
|
|
else:
|
|
|
# LXC:如果没有点赞,添加点赞
|
|
|
post.likes.add(request.user)
|
|
|
liked = True
|
|
|
|
|
|
# LXC:返回JSON响应,包含点赞状态和点赞数量
|
|
|
return JsonResponse({
|
|
|
'liked': liked,
|
|
|
'likes_count': post.likes.count()
|
|
|
})
|
|
|
|
|
|
@login_required
|
|
|
@require_POST
|
|
|
def favorite_post(request, post_id):
|
|
|
"""收藏文章"""
|
|
|
# LXC:获取文章对象
|
|
|
post = get_object_or_404(Post, id=post_id)
|
|
|
|
|
|
# LXC:实现收藏功能逻辑
|
|
|
if post.favorites.filter(id=request.user.id).exists():
|
|
|
# LXC:如果已经收藏,取消收藏
|
|
|
post.favorites.remove(request.user)
|
|
|
favorited = False
|
|
|
else:
|
|
|
# LXC:如果没有收藏,添加收藏
|
|
|
post.favorites.add(request.user)
|
|
|
favorited = True
|
|
|
|
|
|
# LXC:返回JSON响应,包含收藏状态和收藏数量
|
|
|
return JsonResponse({
|
|
|
'favorited': favorited,
|
|
|
'favorites_count': post.favorites.count()
|
|
|
})
|
|
|
|
|
|
@login_required
|
|
|
def edit_post(request, post_id):
|
|
|
"""编辑文章"""
|
|
|
try:
|
|
|
# LXC:获取文章对象,确保作者是当前用户,否则重定向
|
|
|
post = get_object_or_404(Post, id=post_id, author=request.user)
|
|
|
except:
|
|
|
messages.error(request, '您没有权限编辑这篇文章或文章不存在。')
|
|
|
return redirect('user_posts')
|
|
|
|
|
|
if request.method == 'POST':
|
|
|
# LXC:使用POST数据和文件数据初始化表单,并绑定到现有文章实例
|
|
|
form = PostForm(request.POST, request.FILES, instance=post)
|
|
|
if form.is_valid():
|
|
|
form.save()
|
|
|
messages.success(request, '文章更新成功!')
|
|
|
return redirect('user_posts')
|
|
|
else:
|
|
|
messages.error(request, '文章更新失败,请检查表单内容。')
|
|
|
else:
|
|
|
# LXC:GET请求时使用现有文章数据初始化表单
|
|
|
form = PostForm(instance=post)
|
|
|
|
|
|
context = {
|
|
|
'form': form,
|
|
|
'post': post,
|
|
|
'category_info': {
|
|
|
'name': '编辑文章',
|
|
|
'label': '修改创作',
|
|
|
'desc': '修改您的非遗文章内容'
|
|
|
},
|
|
|
'current_path': request.path,
|
|
|
}
|
|
|
return render(request, 'blog/edit_post.html', context) |