有个评论按钮,点击之后跳转到了登录页面,与预算中的不符合
使用了自定义的装饰器修饰视图函数
def login_required(f):
@wraps(f)
def decorated_function(request: HttpRequest, *args, **kwargs):
print("\n" + "🔐" * 30)
print("【装饰器】开始检查")
print(f"请求路径: {request.path}")
print(f"Session中是否有username: {'username' in request.session}")
# if 'username' in request.session:
# print(f"Session中的username: {request.session['username']}")
# print("🔐" * 30 + "\n")
# # 判断 session 中是否存在 'username'
# if 'username' not in request.session:
# # 如果用户未登录,则重定向到登录页面,并将原始URL作为 `next` 参数传递
# return redirect(f"{reverse('login')}?next={request.get_full_path()}")
# return f(request, *args, **kwargs)
if not request.session.get('username'):
print("❌ 未登录,重定向")
return redirect(f"{reverse('login')}?next={request.path}")
print("✅ 已登录,执行视图")
return f(request, *args, **kwargs)
return decorated_function
@login_required
def add_comments(request, movie_id):
"""
添加电影评论
"""
# 获取当前登录用户
username = request.session.get('username')
# userInfo = User.objects.get(username=username)
# userInfo = request.user
if not username:
# 未登录,重定向到登录页
return redirect(f'{settings.LOGIN_URL}?next={request.path}')
try:
userInfo = User.objects.get(username=username)
except User.DoesNotExist:
# 用户不存在,清除 session 并重定向
request.session.flush()
return redirect(f'{settings.LOGIN_URL}?next={request.path}')
# 获取电影信息
movie = get_object_or_404(MovieInfo, movie_id=movie_id)
# 获取该电影的现有评论
existing_comments = getCommentData.get_comments_by_movie(movie.title)
# 检查用户是否已经评论过
already_commented = getCommentData.check_user_commented(movie.title, userInfo.id)
if request.method == 'POST':
if already_commented:
messages.error(request, '您已经评论过这部电影了!')
else:
# 获取表单数据
star = request.POST.get('star')
content = request.POST.get('content')
# 验证数据
if not star or not content:
messages.error(request, '评分和评论内容不能为空!')
else:
# 准备评论数据
comment_data = {
'movie_id': movie_id,
'movie_name': movie.title,
'user_id': userInfo.id,
'user_name': userInfo.username,
'user_url': getattr(userInfo, 'avatar', ''),
'star': star,
'content': content
}
# 保存评论
result = getCommentData.add_comment(comment_data)
if result:
messages.success(request, '评论发布成功!')
return redirect('data_operation')
else:
messages.error(request, '评论发布失败,请重试!')
return render(request, 'add_comments.html', {
'userInfo': userInfo,
'movie': movie,
'existing_comments': existing_comments,
'already_commented': already_commented,
'movie_id': movie_id,
})
def movie_comments(request, movie_id):
"""
电影评论列表页面
"""
username = request.session.get('username')
userInfo = User.objects.get(username=username)
movie = get_object_or_404(MovieInfo, movie_id=movie_id)
comments = getCommentData.get_comments_by_movie(movie.title)
return render(request, 'add_comments.html', {
'userInfo': userInfo,
'movie': movie,
'comments': comments,
})
def get_movie_by_id(movie_id):
"""
根据电影ID获取电影信息
"""
try:
return MovieInfo.objects.get(movie_id=movie_id)
except MovieInfo.DoesNotExist:
return None
def get_comments_by_movie(movie_name):
"""
获取电影的所有评论
"""
return Comment.objects.filter(movie_name=movie_name).order_by('-created_at')
def add_comment(comment_data):
"""
添加评论
comment_data: {
'movie_id': 电影ID,
'movie_name': 电影名称,
'user_id': 用户ID,
'user_name': 用户名,
'user_url': 用户头像,
'star': 评分,
'content': 评论内容
}
"""
try:
comment = Comment.objects.create(
movie_name=comment_data.get('movie_name'),
user_name=comment_data.get('user_name'),
user_url=comment_data.get('user_url', ''),
user_id=comment_data.get('user_id'),
star=float(comment_data.get('star')),
review_date=timezone.now(),
content=comment_data.get('content'),
useful=0
)
return comment
except Exception as e:
print(f"添加评论失败: {e}")
return None
def check_user_commented(movie_name, user_id):
"""
检查用户是否已经评论过该电影
"""
return Comment.objects.filter(
movie_name=movie_name,
user_id=user_id
).exists()
def increment_useful(comment_id):
"""
增加评论的有用数
"""
try:
comment = Comment.objects.get(id=comment_id)
comment.useful += 1
comment.save()
return comment.useful
except Comment.DoesNotExist:
return None
```html
<!-- templates/add_comments.html -->
{% extends 'base.html' %}
{% block title %}添加电影评论{% endblock %}
{% block content %}
<div class="pagetitle" style="display: flex; align-items: center">
<div style="margin-right: auto">
<h1>添加电影评论</h1>
<nav>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'home' %}">主页</a></li>
<li class="breadcrumb-item"><a href="{% url 'data_operation' %}">数据操作</a></li>
<li class="breadcrumb-item active">添加评论</li>
</ol>
</nav>
</div>
</div>
<section class="section">
<div class="row">
<div class="col-lg-8">
<!-- 电影信息卡片 -->
<div class="card mb-3">
<div class="card-body">
<div class="d-flex">
<div style="width: 120px; margin-right: 20px;">
<img src="{{ movie.poster_url }}" alt="{{ movie.title }}"
style="width: 100%; height: 160px; object-fit: cover; border-radius: 8px;">
</div>
<div>
<h4>{{ movie.title }}</h4>
<p class="text-muted mb-2">导演:{{ movie.directors|default:"未知" }}</p>
<p class="text-muted mb-2">类型:{{ movie.genres|default:"未知" }}</p>
<p class="text-muted mb-2">上映年份:{{ movie.release_year|default:"未知" }}</p>
<p class="text-warning mb-0">
<i class="bi bi-star-fill"></i> {{ movie.rating|default:"暂无评分" }}
</p>
</div>
</div>
</div>
</div>
<!-- 评论表单卡片 -->
<div class="card">
<div class="card-body">
<h5 class="card-title">撰写评论</h5>
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
{% endfor %}
{% endif %}
{% if already_commented %}
<div class="alert alert-warning">
<i class="bi bi-exclamation-triangle-fill me-2"></i>
您已经评论过这部电影了,不能重复评论。
</div>
<a href="{% url 'data_operation' %}" class="btn btn-primary">
<i class="bi bi-arrow-left"></i> 返回数据页面
</a>
{% else %}
<form method="post">
{% csrf_token %}
<div class="mb-3">
<label class="form-label fw-bold">评分 <span class="text-danger">*</span></label>
<div class="rating-stars">
<div class="btn-group" role="group">
<input type="radio" class="btn-check" name="star" id="star5" value="5" autocomplete="off">
<label class="btn btn-outline-warning" for="star5">⭐⭐⭐⭐⭐ 非常好</label>
<input type="radio" class="btn-check" name="star" id="star4" value="4" autocomplete="off">
<label class="btn btn-outline-warning" for="star4">⭐⭐⭐⭐ 很好</label>
<input type="radio" class="btn-check" name="star" id="star3" value="3" autocomplete="off">
<label class="btn btn-outline-warning" for="star3">⭐⭐⭐ 一般</label>
<input type="radio" class="btn-check" name="star" id="star2" value="2" autocomplete="off">
<label class="btn btn-outline-warning" for="star2">⭐⭐ 较差</label>
<input type="radio" class="btn-check" name="star" id="star1" value="1" autocomplete="off">
<label class="btn btn-outline-warning" for="star1">⭐ 很差</label>
</div>
</div>
</div>
<div class="mb-3">
<label for="content" class="form-label fw-bold">评论内容 <span class="text-danger">*</span></label>
<textarea class="form-control" id="content" name="content" rows="5"
placeholder="写下你对这部电影的看法..." required></textarea>
<div class="form-text">至少10个字,最多500字</div>
</div>
<div class="mb-3">
<button type="submit" class="btn btn-primary">
<i class="bi bi-check-circle"></i> 发布评论
</button>
<a href="{% url 'data_operation' %}" class="btn btn-secondary">
<i class="bi bi-x-circle"></i> 取消
</a>
</div>
</form>
{% endif %}
</div>
</div>
</div>
<!-- 右侧:已有评论列表 -->
<div class="col-lg-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">
<i class="bi bi-chat-dots-fill me-2"></i>
已有评论 ({{ existing_comments.count }})
</h5>
{% if existing_comments %}
<div class="comments-list" style="max-height: 600px; overflow-y: auto;">
{% for comment in existing_comments %}
<div class="comment-item mb-3 p-3 border-bottom">
<div class="d-flex justify-content-between align-items-center mb-2">
<div class="d-flex align-items-center">
{% if comment.user_url %}
<img src="{{ comment.user_url }}" alt="avatar"
style="width: 30px; height: 30px; border-radius: 50%; margin-right: 10px;">
{% else %}
<div class="bg-secondary text-white rounded-circle d-flex align-items-center justify-content-center"
style="width: 30px; height: 30px; margin-right: 10px;">
<span>{{ comment.user_name|first|upper }}</span>
</div>
{% endif %}
<strong>{{ comment.user_name }}</strong>
</div>
<span class="text-warning">
{% for i in "12345"|make_list %}
{% if forloop.counter <= comment.star %}
<i class="bi bi-star-fill"></i>
{% else %}
<i class="bi bi-star"></i>
{% endif %}
{% endfor %}
</span>
</div>
<p class="mb-2">{{ comment.content|truncatechars:100 }}</p>
<div class="d-flex justify-content-between align-items-center">
<small class="text-muted">{{ comment.review_date|date:"Y-m-d H:i" }}</small>
<span class="text-muted">
<i class="bi bi-hand-thumbs-up"></i> {{ comment.useful }}
</span>
</div>
</div>
{% endfor %}
</div>
{% else %}
<p class="text-muted text-center py-4">暂无评论,快来第一个评论吧!</p>
{% endif %}
</div>
</div>
</div>
</div>
</section>
<style>
.rating-stars .btn-group {
display: flex;
flex-wrap: wrap;
gap: 5px;
}
.rating-stars .btn {
border-radius: 20px !important;
margin: 2px;
}
.comments-list::-webkit-scrollbar {
width: 5px;
}
.comments-list::-webkit-scrollbar-track {
background: #f1f1f1;
}
.comments-list::-webkit-scrollbar-thumb {
background: #888;
border-radius: 5px;
}
.comments-list::-webkit-scrollbar-thumb:hover {
background: #555;
}
</style>
{% endblock %}
```
[06/Mar/2026 10:58:18] "GET /login/?next=/add-comments/35861791/ HTTP/1.1" 200 4210