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

Django更新用户评论报错:Select a valid choice.2不在可选范围内

Django评论更新功能报错:"Select a valid choice. 2 is not one of the available choices" 排查方案

我正在学习Django,开发用户评论修改功能时,点击保存按钮出现错误提示:"Select a valid choice. 2 is not one of the available choices"。参照教程中的地址簿更新逻辑编写代码,地址簿修改功能正常,但评论更新功能报错,已排查数小时未找到问题,相关代码如下:

models.py

class ProductReview(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    review_text = models.TextField()
    review_rating = models.CharField(choices=RATING, max_length=150)

    def get_review_rating(self):
        return self.review_rating

class UserAddressBook(models.Model):
    user = models.ForeignKey(User,on_delete=models.CASCADE)
    mobile = models.CharField(max_length=12, null=True)
    address = models.TextField()
    status = models.BooleanField(default=False)

views.py

def my_reviews(request):
    reviews = ProductReview.objects.filter(user=request.user).order_by('-id')
    return render(request, 'user/reviews.html', {'reviews':reviews})

def save_review(request, pid):
    product = Product.objects.get(pk=pid)
    user = request.user
    review = ProductReview.objects.create(
        user=user,
        product=product,
        review_text=request.POST['review_text'],
        review_rating=request.POST['review_rating'],
    )
    data = {
        'user': user.username,
        'review_text': request.POST['review_text'],
        'review_rating': request.POST['review_rating'],
    }

    avg_reviews = ProductReview.objects.filter(product=product).aggregate(avg_rating=Avg('review_rating'))

    return JsonResponse({'bool': True, 'data': data, 'avg_reviews': avg_reviews})

def update_review(request, id):
    review = ProductReview.objects.get(pk=id)
    if request.method=='POST':
        form = ReviewAdd(request.POST,instance=review)
        if form.is_valid():
            saveForm = form.save(commit=False)
            saveForm.user=request.user
            saveForm.save()
            return redirect('/my-reviews')
    else:
        form=ReviewAdd(instance=review)
    return render(request, 'user/update-review.html', {'form':form})

def my_addressbook(request):
    addbook = UserAddressBook.objects.filter(user=request.user).order_by('-id')
    return render(request, 'user/addressbook.html', {'addbook':addbook})

def save_address(request):
    msg = None
    if request.method=='POST':
        form=AddressBookForm(request.POST)
        if form.is_valid():
            saveForm = form.save(commit=False)
            saveForm.user = request.user
            if 'status' in request.POST:
                UserAddressBook.objects.update(status=False)
            saveForm.save()
            msg='Address changed'
            return redirect('/my-addressbook')
    form=AddressBookForm
    return render(request, 'user/add-address.html', {'form':form, 'msg':msg})

def activate_address(request):
    a_id = str(request.GET['id'])
    UserAddressBook.objects.update(status=False)
    UserAddressBook.objects.filter(id=a_id).update(status=True)
    return JsonResponse({'bool':True})

def delete_address(request):
    a_id = str(request.GET['id'])
    UserAddressBook.objects.filter(id=a_id).delete()
    return JsonResponse({'bool': True})

def update_address(request,id):
    address = UserAddressBook.objects.get(pk=id)
    msg=None
    if request.method=='POST':
        form = AddressBookForm(request.POST,instance=address)
        if form.is_valid():
            saveForm = form.save(commit=False)
            saveForm.user=request.user
            if 'status' in request.POST:
                UserAddressBook.objects.update(status=False)
            saveForm.save()
            msg = 'Address changed'
            return redirect('/my-addressbook')
    form=AddressBookForm(instance=address)
    return render(request, 'user/update-address.html', {'form':form, 'msg':msg})

urls.py

from django.urls import path, include
from . import views

from django.conf import settings
from django.conf.urls.static import static

urlpatterns=[
   path('', views.home, name='home'),
   path('my-reviews',views.my_reviews, name='my-reviews'),
   path('save-review/<int:pid>', views.save_review, name='save_review'),
   path('update-review/<int:id>',views.update_review, name='update-review'),
   path('my-addressbook',views.my_addressbook, name='my-addressbook'),
   path('add-address', views.save_address, name='add_address'),
   path('update-address/<int:id>',views.update_address, name='update-address'),
   path('delete-address', views.delete_address, name='delete-address'),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

reviews.html

{% extends 'base.html' %}
{% load static %}
{% block content %}
<main class="container my-4">
    <h3 class="my-4 border-bottom pb-1">Reviews</h3>
    <div class="row">
        <div class="col-md-3">
            {% include 'user/user-sidebar.html' %}
        </div>
        <div class="col-md-9">
            <div class="table-responsive">
                <table class="table-bordered table">
                    <thead>
                        <tr>
                            <th>Title</th>
                            <th>Image</th>
                            <th>Price</th>
                            <th>Review text</th>
                            <th>Review rating</th>
                        </tr>
                    </thead>
                    <tbody>
                        {% for review in reviews %}
                        <tr>
                            <td><a href="/product/{{review.product.id}}">{{review.product.title}}</a></td>
                            <td>
                                <img width="100" src="/media/{{review.product.image}}" alt="{{review.product.title}}">
                            </td>
                            <td>{{review.product.price}}</td>
                            <td>
                                <a href="{% url 'update-review' review.id %}" class="float-right"><i class="fa fa-edit"></i></a>
                                {{review.review_text}}
                            </td>
                            <td>{{review.review_rating}}</td>
                        </tr>
                        {% endfor %}
                    </tbody>
                </table>
            </div>
        </div>
    </div>
</main>
{% endblock %}

update-review.html

{% extends 'base.html' %}
{% load static %}
{% block content %}
<main class="container my-4">
    <h3 class="my-4 border-bottom pb-1">Change review</h3>
    <div class="row">
        <div class="col-md-3">
            {% include 'user/user-sidebar.html' %}
        </div>
        <div class="col-md-9">
            {% if msg %}
            <p class="text-success">{{msg}}</p>
            {% endif %}
            <table class="table table-bordered">
                <form method="post">
                    {% csrf_token %}
                    {{form.as_table}}
                    <tr>
                        <td colspan="2">
                            <input type="submit" value="Save" class="btn btn-primary" />
                        </td>
                    </tr>
                </form>
            </table>
        </div>
    </div>
</main>
{% endblock %}

问题原因及解决步骤

核心原因

错误提示说明提交的review_rating值(比如2)不在字段定义的choices选项范围内,或者RATING常量的定义不符合Django要求。

解决步骤

  1. 检查RATING常量定义
    确保RATING是二元组列表格式,示例如下:

    RATING = [
        ('1', '1星'),
        ('2', '2星'),
        ('3', '3星'),
        ('4', '4星'),
        ('5', '5星'),
    ]
    

    注意:元组第一个元素是存储到数据库的字符串值(与CharField类型匹配),第二个是前端显示的文本。

  2. 验证表单ReviewAdd的正确性
    确保表单正确关联模型,自动继承字段的choices配置:

    from django import forms
    from .models import ProductReview
    
    class ReviewAdd(forms.ModelForm):
        class Meta:
            model = ProductReview
            fields = ['review_text', 'review_rating']
    

    若自定义了表单字段,需保证choices与模型RATING完全一致。

  3. 检查数据库现有数据
    如果RATING定义曾修改过,可能存在旧数据不符合当前选项的情况。通过Django shell查询并修正:

    # 进入Django shell
    python manage.py shell
    # 查询所有评论的rating值
    from your_app_name.models import ProductReview
    for review in ProductReview.objects.all():
        print(review.review_rating)
    # 修正不符合的值
    ProductReview.objects.filter(review_rating='2').update(review_rating='2')  # 替换为合法选项
    
  4. 清理视图冗余代码
    update_review视图中saveForm.user=request.user是冗余操作(评论已关联当前用户),可删除该行,避免不必要的字段赋值。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 09:17:06