You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django医生服务评分评论视图实现咨询(含双用户角色)

Django 评分评论功能视图实现方案

一、提交评分评论的视图(处理POST请求)

函数视图实现

from django.shortcuts import get_object_or_404, redirect, render
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from .models import Doctor, RatingReview
from .forms import RatingReviewForm

@login_required
def submit_rating_review(request, doctor_id):
    doctor = get_object_or_404(Doctor, id=doctor_id)
    # 验证当前用户为患者(假设用户模型含is_patient字段)
    if not request.user.is_patient:
        messages.error(request, "仅患者可提交评分评论")
        return redirect('doctor_detail', doctor_id=doctor_id)
    
    if request.method == 'POST':
        form = RatingReviewForm(request.POST)
        if form.is_valid():
            rating_review = form.save(commit=False)
            rating_review.patient = request.user
            rating_review.doctor = doctor
            rating_review.save()
            messages.success(request, "评分评论提交成功")
            return redirect('doctor_detail', doctor_id=doctor_id)
    else:
        form = RatingReviewForm()
    
    return render(request, 'submit_rating.html', {'form': form, 'doctor': doctor})

核心说明:

  • @login_required限制仅登录用户访问
  • 先校验用户身份,防止医生或其他角色提交评论
  • POST请求时,先验证表单有效性,再关联患者和医生对象后保存
  • 用messages组件返回操作反馈,提升用户体验
  • 非POST请求返回空表单页面,供用户填写

类视图实现(可选)

from django.views.generic.edit import CreateView
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.urls import reverse_lazy
from django.shortcuts import get_object_or_404
from django.contrib import messages
from .models import Doctor, RatingReview
from .forms import RatingReviewForm

class RatingReviewCreateView(LoginRequiredMixin, UserPassesTestMixin, CreateView):
    model = RatingReview
    form_class = RatingReviewForm
    template_name = 'submit_rating.html'
    
    def test_func(self):
        # 校验用户是否为患者
        return self.request.user.is_patient
    
    def form_valid(self, form):
        doctor = get_object_or_404(Doctor, id=self.kwargs['doctor_id'])
        form.instance.patient = self.request.user
        form.instance.doctor = doctor
        messages.success(self.request, "评分评论提交成功")
        return super().form_valid(form)
    
    def get_success_url(self):
        return reverse_lazy('doctor_detail', kwargs={'doctor_id': self.kwargs['doctor_id']})
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['doctor'] = get_object_or_404(Doctor, id=self.kwargs['doctor_id'])
        return context

核心说明:

  • 借助Django内置的CreateView快速实现创建逻辑
  • LoginRequiredMixin和UserPassesTestMixin组合实现登录与身份双重校验
  • form_valid方法完成评论与患者、医生的关联
  • get_success_url指定提交成功后的跳转目标

二、展示评分评论的视图

医生详情页集成评论展示

在医生详情视图中,获取对应医生的评论数据并传递到模板:

from django.shortcuts import get_object_or_404, render
from django.db.models import Avg
from .models import Doctor, RatingReview

def doctor_detail(request, doctor_id):
    doctor = get_object_or_404(Doctor, id=doctor_id)
    # 获取该医生的所有评论,按创建时间倒序排列
    rating_reviews = RatingReview.objects.filter(doctor=doctor).order_by('-created_at')
    # 计算平均评分,无评论时默认0.0
    average_rating = rating_reviews.aggregate(Avg('rating'))['rating__avg'] or 0.0
    
    context = {
        'doctor': doctor,
        'rating_reviews': rating_reviews,
        'average_rating': round(average_rating, 1)
    }
    return render(request, 'doctor_detail.html', context)

核心说明:

  • 用filter筛选指定医生的评论,order_by('-created_at')实现最新评论优先展示
  • 借助aggregate和Avg聚合函数计算平均评分,处理无评论的边界情况
  • 将评论列表、平均评分与医生对象一起传递到模板,供前端渲染

独立评论列表视图(可选)

如果需要单独的评论分页页面:

from django.views.generic.list import ListView
from django.shortcuts import get_object_or_404
from .models import RatingReview, Doctor

class DoctorRatingReviewListView(ListView):
    model = RatingReview
    template_name = 'rating_review_list.html'
    paginate_by = 10  # 每页展示10条评论
    
    def get_queryset(self):
        doctor = get_object_or_404(Doctor, id=self.kwargs['doctor_id'])
        return RatingReview.objects.filter(doctor=doctor).order_by('-created_at')
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['doctor'] = get_object_or_404(Doctor, id=self.kwargs['doctor_id'])
        return context

核心说明:

  • 继承ListView快速实现列表展示与分页功能
  • get_queryset方法过滤出指定医生的评论数据
  • 传递医生对象到模板,方便页面展示医生基本信息

三、权限与边界控制要点

  • 重复评论拦截:可在视图中添加判断,若当前患者已对该医生提交过评论,直接返回错误提示:
    if RatingReview.objects.filter(patient=request.user, doctor=doctor).exists():
        messages.error(request, "您已对该医生提交过评论")
        return redirect('doctor_detail', doctor_id=doctor_id)
    
  • 内容合规性:可在forms.py的clean_content方法中添加内容过滤逻辑,拦截违规词汇
  • 匿名控制:若需隐藏患者真实信息,可在模板中展示患者昵称而非用户名

四、模板集成提示

  • 提交表单:确保表单包含{% csrf_token %},action属性指向提交视图的URL
  • 评论渲染:遍历rating_reviews列表,展示评分(可通过CSS渲染星级图标)、评论内容、发布时间等
  • 平均评分:直接使用{{ average_rating }}配合星级组件展示,直观呈现医生口碑

内容的提问来源于stack exchange,提问作者Rachid Mayene

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 23:45:34