Django 網站如何新增「星星評分」功能 — 後端接收邏輯

更新日期: 2025 年 1 月 7 日

在 Django 專案中,當需要在留言功能中加入「星星評分」的功能時,如何以最少的修改達成這個需求呢?

這篇文章將逐步解釋如何在你的 models.pyforms.pyviews.py 中新增 rating 欄位,並確保資料能被正確儲存。


目標與現狀說明

目前的程式邏輯

  • Comment 模型 只包含 content 欄位,沒有 rating 欄位。
  • CommentForm 表單 目前僅處理 content
  • service_detail 視圖 只儲存 content,沒有考慮評分邏輯。

目標

讓前端的星星評分能夠正確傳送到後端並儲存。


修改 models.py (新增 rating 欄位)

為了儲存評分,我們需要在 Comment 模型中新增一個 rating 欄位,並限制其範圍為 1 到 5 分之間。

# models.py
from django.core.validators import MinValueValidator, MaxValueValidator
from django.db import models
from django.contrib.auth.models import User
from services.models import Service

class Comment(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="comments")
    service = models.ForeignKey(Service, on_delete=models.CASCADE, related_name="comments")
    content = models.TextField()
    rating = models.PositiveSmallIntegerField(  
        null=True, 
        blank=True, 
        validators=[MinValueValidator(1), MaxValueValidator(5)]  # ✅ 限制範圍在 1-5 分
    )
    created_at = models.DateTimeField(auto_now_add=True)
    deleted_at = models.DateTimeField(null=True, blank=True)
    is_deleted = models.BooleanField(default=False)

    def __str__(self):
        return self.content[:20]

執行資料庫遷移

python manage.py makemigrations
python manage.py migrate

修改 forms.py (更新表單欄位)

為了讓前端可以傳送 rating,我們需要在 CommentForm 表單中加入 rating 欄位。

# forms.py
from django import forms
from .models import Comment

class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ["content", "rating"]  # ✅ 加入 rating 欄位

修改 views.py (接收並儲存 rating 資料)

service_detail 視圖中,讓後端能夠接收到 POST 請求中的 rating 並正確儲存。

# views.py
from django.shortcuts import render, get_object_or_404, redirect
from .models import Comment
from .forms import CommentForm
from services.models import Service
from django.contrib.auth.decorators import login_required

@login_required
def service_detail(request, id, service_id):
    service = get_object_or_404(Service, id=service_id)
    comments = Comment.objects.filter(service=service, is_deleted=False).order_by(
        "-created_at"
    )
    form = CommentForm()

    if request.method == "POST":
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False)
            comment.user = request.user
            comment.service = service
            comment.rating = request.POST.get("rating")  # ✅ 儲存 rating
            comment.save()
            return redirect(
                "services:service_detail", id=request.user.id, service_id=service_id
            )

    return render(
        request,
        "services/service_detail.html",
        {
            "service": service,
            "comments": comments,
            "form": form,
        },
    )

測試流程

後端測試

  1. 提交評論後,檢查資料庫:
python manage.py shell
>>> from comments.models import Comment
>>> Comment.objects.all().values('content', 'rating')
  1. 確認資料庫中是否正確儲存了 contentrating

總結

  1. 模型 (models.py):新增了 rating 欄位,並限制範圍在 1 到 5。
  2. 表單 (forms.py):在表單中新增 rating 欄位,並使用隱藏輸入框。
  3. 視圖 (views.py):修改了 service_detail 視圖,接收 rating 並儲存。

這是一個 最小化改動 的解決方案,在不影響既有功能的前提下,成功讓 Django 專案具備了「星星評分」功能。

Similar Posts

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *