Django中如何将views.py获取的表格ID关联交易实现筛选
实现思路
你想的方向完全对,要实现不同表格下的交易隔离,核心就是两张表建立关联,拿当前URL里的表格ID绑定到新交易上,查询时只取当前表格关联的交易即可。
现有代码里的硬伤
- models.py里第一行
from .views import table属于循环导入,启动服务直接报错,必须删掉 - Transacao模型里误写的
mod = models没有任何作用,直接删除 - Table模型没必要自定义
idd当主键,Django默认自动生成的自增id完全够用,自定义主键只会给后续关联增加额外配置成本 - 原来table视图里
return render(...),pk的写法是错的,相当于把HttpResponse对象包成了元组,Django无法识别,会直接抛异常 - 现在的表格详情页误用了新建表格的TableForm,根本没有加载交易表单,也没有查询交易数据
逐文件改造代码
1. 修改models.py
建立两张表的外键关联,删除无效代码:
from django.db import models class Table(models.Model): name = models.CharField(max_length=100) date = models.DateField(auto_now_add=True) time = models.TimeField(auto_now_add=True) class Meta: verbose_name_plural = 'Tables' def __str__(self): return self.name class Transacao(models.Model): # 外键关联到Table,设置级联删除,表格删除时对应的交易同步删除 linked_table = models.ForeignKey( Table, on_delete=models.CASCADE, related_name='transactions' ) date = models.DateTimeField() desc = models.CharField(max_length=200) value = models.DecimalField(max_digits=7, decimal_places=2) obs = models.TextField(null=True, blank=True) class Meta: verbose_name_plural = 'Transacoes' def __str__(self): return self.desc
模型修改完成后,依次执行
python manage.py makemigrations、python manage.py migrate生成新的数据库表结构
2. 修正forms.py
补全缺失的父类导入,调整交易表单的字段配置:
from django.forms import ModelForm from .models import Table, Transacao class TableForm(ModelForm): class Meta: model = Table fields = ['name'] class TransacaoForm(ModelForm): class Meta: model = Transacao # 关联表格的字段不需要展示在表单上,我们在视图层自动赋值 fields = ['desc', 'date', 'value', 'obs']
3. 重写table视图逻辑
视图要完成三个核心动作:
- 根据URL里的pk取出当前对应的表格对象,表格不存在时直接返回404
- 处理交易表单提交,保存时自动绑定当前表格对象,不需要用户手动选择归属
- 查询当前表格下的所有交易,传给页面展示
修正后的代码:
from django.shortcuts import render, redirect, get_object_or_404 from .models import Table from .forms import TransacaoForm def table(request, pk): current_table = get_object_or_404(Table, pk=pk) trans_form = TransacaoForm(request.POST or None) if trans_form.is_valid(): # 先不直接入库,拿到表单实例后绑定当前表格,再执行保存 new_trans = trans_form.save(commit=False) new_trans.linked_table = current_table new_trans.save() # 保存完成后重定向回当前页面,避免刷新时重复提交表单 return redirect('tableurl', pk=current_table.pk) # 取当前表格下的所有交易,按日期倒序排列 table_transactions = current_table.transactions.all().order_by('-date') return render(request, 'tables1/table.html', { 'data': current_table, 'trans_form': trans_form, 'transactions': table_transactions })
原来放在这个视图里的TableForm已经不需要了,新建表格的逻辑已经在
newtable视图里实现
4. 调整模板渲染逻辑
在table.html中:
- 把原来误放的新建表格表单替换成
trans_form,表单提交地址指向当前的table路由,带上当前表格的pk - 循环遍历传入的
transactions列表,把每笔交易的日期、描述、金额、备注展示在页面上
最终运行效果
打开id=1的table1页面时,系统自动加载这个表格的所有关联交易,新建交易时自动把交易归属绑定到table1;打开id=2的table2页面时,只会加载table2下的关联交易,完全实现不同表格的交易隔离。
内容的提问来源于stack exchange,提问作者Gustavo Marinho
相关产品推荐
相关产品推荐

