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

Django实现注册表单下拉框从数据库加载分类数据

Django商品注册表单下拉框加载分类数据解决方案

问题分析

当前代码存在几个核心问题:

  • 商品模型CadastroProduto的codcategoria字段是CharField,未与分类模型CadastroCategoria建立正确外键关联,无法实现数据关联查询与选择
  • 缺少处理商品表单的专属视图,现有ListagemCategorias视图仅服务于分类列表页面,未向cadproduto.html传递分类数据
  • 表单类ProdutoForm未包含分类字段,无法渲染分类选择控件

分步修改方案

1. 修正模型关联(models.py)

将CadastroProduto中的codcategoria改为外键,关联CadastroCategoria,这是实现分类选择的基础:

from django.db import models

class CadastroProduto(models.Model):
    STATUS = (
        ('Ativo','Ativo'),
        ('Inativo','Inativo'),
    )

    descricaoresumida = models.CharField("Descrição Item", max_length=120)
    enviabalanca = models.BooleanField("Enviar p/ Balança", default=False)
    aliquota = models.CharField("Alíquota", max_length=20)
    # 替换原CharField为外键关联
    codcategoria = models.ForeignKey(
        CadastroCategoria,
        on_delete=models.PROTECT,  # 防止分类被删除时关联商品丢失
        verbose_name="Categoria"
    )
    unidademedida = models.CharField("Unidade de Medida", max_length=3)
    ncm = models.CharField('N.C.M.', max_length=12)
    codsetor = models.CharField("Setor", max_length=8)
    codsubcategoria = models.CharField("Sub-Categoria", max_length=8)
    precoprincipal = models.DecimalField(max_digits=10, decimal_places=2)

    ativo = models.CharField(
        max_length=7,
        choices=STATUS,
    )

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.descricaoresumida

class CadastroCategoria(models.Model):
    STATUS = (
        ('Ativo','Ativo'),
        ('Inativo','Inativo'),
    )

    descricaocategoria = models.CharField("Descrição Item", max_length=120)
    
    ativo = models.CharField(
        max_length=7,
        choices=STATUS,
    )

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.descricaocategoria

2. 更新表单类(forms.py)

在ProdutoForm中添加codcategoria字段,让Django自动渲染分类下拉框:

from django import forms
from .models import CadastroProduto

class ProdutoForm(forms.ModelForm):
    class Meta:
        model = CadastroProduto
        # 添加codcategoria字段到表单
        fields = ('descricaoresumida', 'precoprincipal', 'enviabalanca', 'codcategoria')

3. 编写商品表单视图(views.py)

创建处理商品注册的视图,查询分类并传递给模板,同时处理表单提交:

from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from .models import CadastroCategoria
from .forms import ProdutoForm

@login_required
def CadastroProdutoView(request):
    # 查询所有启用的分类(可根据需求过滤)
    ListaDeCategorias = CadastroCategoria.objects.filter(ativo='Ativo')
    if request.method == 'POST':
        form = ProdutoForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('produto_listagem')  # 替换为你的商品列表页面路由
    else:
        form = ProdutoForm()
    # 传递表单和分类数据到模板
    return render(request, 'cadproduto.html', {'form': form, 'ListaDeCategorias': ListaDeCategorias})

4. 修改模板渲染(cadproduto.html)

提供两种渲染方式,按需选择:

方式一:使用Django表单自动渲染(推荐)
<form method="post">
    {% csrf_token %}
    <!-- 其他表单字段 -->
    <div class="form-group">
        <label for="{{ form.codcategoria.id_for_label }}">Categoria:</label>
        {{ form.codcategoria }}
    </div>
    <!-- 提交按钮 -->
    <button type="submit" class="btn btn-primary">Salvar Produto</button>
</form>
方式二:手动渲染下拉框(保留原有写法)
<form method="post">
    {% csrf_token %}
    <!-- 其他表单字段 -->
    <div class="form-group">
        <label for="exampleFormControlSelect1">Categoria:</label>
        <select class="form-control select" id="exampleFormControlSelect1" name="codcategoria">
            {% for categoria in ListaDeCategorias %}
            <option value="{{ categoria.id }}">{{ categoria.descricaocategoria }}</option>
            {% endfor %}
        </select>
    </div>
    <!-- 提交按钮 -->
    <button type="submit" class="btn btn-primary">Salvar Produto</button>
</form>

收尾步骤

  1. 执行数据库迁移,更新模型变更:
python manage.py makemigrations
python manage.py migrate
  1. 在urls.py中配置商品注册视图的路由:
from django.urls import path
from . import views

urlpatterns = [
    # 其他路由
    path('cadastro-produto/', views.CadastroProdutoView, name='cadastro_produto'),
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 15:10:53