Django新增Product报错:Product.category需为Category实例如何解决
报错原因
- 外键字段赋值规则问题:Django的ForeignKey字段要求赋值为关联模型的实例,或者对应关联表数据的主键ID,你当前从表单获取到的
category、subcategory都是分类名称字符串,直接赋值给外键字段就会触发该错误。 - 模板下拉框配置错误:模板中下拉选项没有设置
value属性,提交表单时传递的是选项显示的文本内容,不是分类/子分类的主键ID。 - 额外隐藏问题:
Product模型的__str__方法语法不完整,后续调用实例字符串表示时会报错。
修复步骤
1. 修正视图逻辑(views.py)
调整POST数据处理逻辑,直接使用外键ID后缀赋值,无需额外查询数据库获取实例,同时提前查询全量分类、子分类数据传给模板,避免无产品时下拉框为空的问题:
from django.shortcuts import render from .models import Product, Category, SubCategory def home(request): categories = Category.objects.all() subcategories = SubCategory.objects.all() if request.method == "POST": name = request.POST['name'] subcategory_id = request.POST['subcategory'] category_id = request.POST['category'] # 直接用外键字段+_id的方式赋值主键,符合Django语法规则 ins = Product(name=name, subcategory_id=subcategory_id, category_id=category_id) ins.save() data = Product.objects.all() return render(request, 'mysiteapp/index.html', {'data': data, 'categories': categories, 'subcategories': subcategories})
2. 修正模板下拉框配置(index.html)
修改分类、子分类的下拉选项,设置value为对应数据的主键ID,同时直接遍历全量分类数据生成选项:
子分类下拉框修改
<select name="subcategory" class="custom-select mr-sm-2" id="subcategory"> <option>Choose....</option> {% for sub in subcategories %} <option value="{{sub.id}}">{{sub.name}}</option> {% endfor %} </select>
分类下拉框修改
<select name="category" class="custom-select mr-sm-2" id="category"> <option>Choose....</option> {% for cat in categories %} <option value="{{cat.id}}">{{cat.name}}</option> {% endfor %} </select>
3. 修正模型语法错误(models.py)
补全Product模型的__str__方法:
class Product(models.Model): name = models.CharField(max_length=100, db_index=True) category = models.ForeignKey(Category, on_delete=models.CASCADE) subcategory = models.ForeignKey(SubCategory, on_delete=models.CASCADE) def __str__(self): return self.name
可选优化
可以在视图中添加异常捕获逻辑,处理提交的分类ID不存在、参数缺失的情况,避免程序崩溃。
内容的提问来源于stack exchange,提问作者user16775421
相关产品推荐
相关产品推荐

