Django五星评分评论系统问题:表单提交后评论未存入数据库
核心问题分析与修复方案
1. 模板表单的致命错误修复
你的模板存在字段重复引用、表单闭合位置错误、缺少CSRF令牌、无星级值存储字段这几个关键问题,直接导致表单数据无法正确提交:
修复后的模板代码:
<form method="post"> {% csrf_token %} <div class="form-singel"> {{ form.first_name|attr:"placeholder:First Name" }} </div> <div class="form-singel"> {{ form.last_name|attr:"placeholder:Last Name" }} </div> <div class="rate-label">Your Rating:</div> <div class="rate"> <div data-value="1" class="rate-item"><i class="fa fa-star" aria-hidden="true"></i></div> <div data-value="2" class="rate-item"><i class="fa fa-star" aria-hidden="true"></i></div> <div data-value="3" class="rate-item"><i class="fa fa-star" aria-hidden="true"></i></div> <div data-value="4" class="rate-item"><i class="fa fa-star" aria-hidden="true"></i></div> <div data-value="5" class="rate-item"><i class="fa fa-star" aria-hidden="true"></i></div> <!-- 隐藏字段存储选中的星级值 --> <input type="hidden" name="rating" id="rating-input" value=""> </div> <div class="form-singel"> {{ form.comment|attr:"placeholder:Comment" }} </div> <div class="form-singel"> <button type="submit" class="main-btn">Post Comment</button> </div> </form>
- 修正了
last_name和comment字段的引用错误 - 调整表单闭合位置,将评论输入框和提交按钮纳入表单范围内
- 添加Django必填的
{% csrf_token %} - 新增隐藏字段
rating-input用于存储用户选中的星级值
2. JavaScript逻辑重构
原AJAX会在点击星级时直接提交数据,导致未填写完整表单就创建空评论,正确逻辑是点击星级时仅更新隐藏字段值,等待用户填完所有信息后统一提交:
修复后的JavaScript代码:
$(document).ready(function(){ $('.rate .rate-item').on('click', function(){ var value = $(this).data('value'); // 更新隐藏字段的星级值 $('#rating-input').val(value); // 可选:添加星级高亮效果 $('.rate-item').removeClass('active'); $(this).addClass('active').prevAll().addClass('active'); }); });
3. 视图函数优化
移除不安全的@csrf_exempt,处理星级值的类型转换,同时增加表单验证失败的容错处理:
修复后的视图代码:
def productDetailView(request, id, slug): product = get_object_or_404(Product, id=id, slug=slug, available=True) new_comment = None if request.method == 'POST': form = ReviewForm(request.POST) # 获取星级值,处理用户未选择星级的情况 rating = request.POST.get('rating') if form.is_valid() and rating: new_comment = form.save(commit=False) new_comment.course = product # 将字符串类型的rating转为整数 new_comment.rating = int(rating) new_comment.save() # 提交成功后重置表单 form = ReviewForm() else: form = ReviewForm() return render(request, 'shop/product_detail.html', { 'product': product, 'form': form, 'new_comment': new_comment })
4. 表单类补充
确保你的ReviewForm包含所需字段,示例代码:
from django import forms from .models import Review class ReviewForm(forms.ModelForm): class Meta: model = Review fields = ['first_name', 'last_name', 'comment']
额外调试建议
- 在模板中添加
{{ form.errors }},可以直观看到表单验证失败的原因 - 可以在视图中临时添加
print(request.POST)和print(form.errors),排查提交的数据是否正确 - 给星级添加高亮CSS,提升用户体验:
.rate-item.active i { color: #ffc107; }
内容的提问来源于stack exchange,提问作者MMEEUR
相关产品推荐
相关产品推荐

