如何在Django中结合自定义HTML模板按类别添加产品
问题描述
在Django项目中,通过表单选择类别添加产品时,产品成功存入数据库,但关联的类别字段categ始终显示为None,求问题原因及解决方法。
相关代码
views.py
def addpro(request): cat = Category.objects.all() if request.method == 'POST': name = request.POST.get('name') price = request.POST.get('price') stock = request.POST.get('stock') cate = request.POST.get('category') img = request.FILES['img'] obj = FileSystemStorage() img2 = obj.save(img.name, img) if Product.objects.filter(name=name).exists(): return redirect('add') else: Product.objects.create(name=name, price=price, stock=stock , image=img2 , categ = cate ) return redirect('add') return render(request, 'Add.html',{'category':cat})
models.py
from django.db import models class Category(models.Model): Name = models.CharField(max_length=30 , null = True) def __str__(self): return str(self.Name) class Product(models.Model): name = models.CharField(max_length=255) price = models.IntegerField(null = True) stock = models.IntegerField(null = True) image = models.ImageField(upload_to='product/',null =True) categ = models.ForeignKey("Category", on_delete=models.CASCADE,null = True) def __str__(self): return self.name
模板中的类别选择代码
<div class="form-group"> <label><strong>Category</strong></label> <select name="categ" class="custom-select mr-sm-2" id="inlineFormCustomSelect"> {% for cat in category %} <option id="category" selected="selected" value="{{ cat.id }}">{{cat.Name}}</option> {% endfor %} </select> </div>
问题原因及修复方案
核心问题1:表单参数获取键名不匹配
模板中<select>标签的name属性是categ,但视图里用request.POST.get('category')获取参数,键名完全不一致,导致cate变量拿到的是None,最终存入数据库的categ字段自然也是None。
核心问题2:ForeignKey字段赋值不规范
即使键名正确,直接将获取到的字符串类型的类别ID传给ForeignKey字段,虽然Django可能会自动转换,但更规范的做法是使用categ_id参数直接传入ID,或者先获取对应的Category对象再赋值。
修复后的views.py代码
def addpro(request): cat = Category.objects.all() if request.method == 'POST': name = request.POST.get('name') price = request.POST.get('price') stock = request.POST.get('stock') # 修正:使用表单中select的name属性值'categ'获取参数 cate_id = request.POST.get('categ') img = request.FILES['img'] obj = FileSystemStorage() img2 = obj.save(img.name, img) if Product.objects.filter(name=name).exists(): return redirect('add') else: # 修正:使用categ_id直接传入ID,或者通过Category.objects.get(id=cate_id)获取对象传入 Product.objects.create( name=name, price=price, stock=stock, image=img2, categ_id=cate_id # 这里用categ_id对应ForeignKey的ID字段 ) return redirect('add') return render(request, 'Add.html',{'category':cat})
额外优化:模板中selected属性问题
当前模板里所有<option>都加了selected="selected",这会导致页面加载时默认选中最后一个类别,体验不佳。建议只给需要默认选中的选项添加该属性,比如添加一个空选项作为默认:
<div class="form-group"> <label><strong>Category</strong></label> <select name="categ" class="custom-select mr-sm-2" id="inlineFormCustomSelect"> <option value="">请选择类别</option> {% for cat in category %} <option value="{{ cat.id }}">{{cat.Name}}</option> {% endfor %} </select> </div>
内容的提问来源于stack exchange,提问作者Cat Logic
相关产品推荐
相关产品推荐

