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要求。
解决步骤
检查
RATING常量定义
确保RATING是二元组列表格式,示例如下:RATING = [ ('1', '1星'), ('2', '2星'), ('3', '3星'), ('4', '4星'), ('5', '5星'), ]注意:元组第一个元素是存储到数据库的字符串值(与
CharField类型匹配),第二个是前端显示的文本。验证表单
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完全一致。检查数据库现有数据
如果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') # 替换为合法选项清理视图冗余代码
update_review视图中saveForm.user=request.user是冗余操作(评论已关联当前用户),可删除该行,避免不必要的字段赋值。
内容的提问来源于stack exchange,提问作者Artem
相关产品推荐
相关产品推荐

