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>
收尾步骤
- 执行数据库迁移,更新模型变更:
python manage.py makemigrations python manage.py migrate
- 在
urls.py中配置商品注册视图的路由:
from django.urls import path from . import views urlpatterns = [ # 其他路由 path('cadastro-produto/', views.CadastroProdutoView, name='cadastro_produto'), ]
内容的提问来源于stack exchange,提问作者Elinton Soares
相关产品推荐
相关产品推荐

