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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 05:45:31