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

Django表单处理:创建Transaction并关联为AccountBooking外键报错

问题描述

处理ModelForm时,希望不让用户填写fk_transaction字段,后台自动创建一条Transaction记录并关联到AccountBooking。表单显示正常,Transaction能创建,但视图中尝试将记录添加到表单保存时,提示该字段不存在。

代码片段

views.py

from django.http import HttpResponse
from django.shortcuts import render
from forms import AccountBookingForm
from models import Transaction


def deposit(request):
    context = {}
    if request.method == "POST":
        form = AccountBookingForm(request.POST)
        t = Transaction()
        form.fk_transaction = t
        form.save()
        return render(request, "deposit_success.html", {"form": form})
    else:
        form = AccountBookingForm()
        return render(request, "deposit.html", {"form": form})

models.py

class Transaction(models.Model):
    type = models.CharField(max_length=11, choices=TR_TYPE_CHOICES, default=DEPOSIT)
    status = models.CharField(max_length=11, choices=TR_STATUS_CHOICES, default=DRAFT)
    text = models.TextField(max_length=500, default="", blank=True)


class AccountBooking(models.Model):
    fk_bankaccount = models.ForeignKey(
        BankAccount, on_delete=models.CASCADE, blank=False)
    fk_transaction = models.ForeignKey(Transaction, on_delete=models.CASCADE, blank=False)
    value = models.DecimalField(max_digits=14, decimal_places=2, blank=False)

forms.py

from django.forms import ModelForm
from .models import AccountBooking

class AccountBookingForm(ModelForm):
    class Meta:
        model = AccountBooking
        fields = ["__all__"]
        exclude = ("fk_transaction",)
解决方案

问题出在直接给form对象赋值fk_transaction——因为你已经在表单中排除了这个字段,form实例上不存在该属性。正确操作步骤:

  1. 先保存Transaction记录(外键必须关联已存在的数据库记录)
  2. 使用form.save(commit=False)获取未写入数据库的AccountBooking实例
  3. 给该实例补充fk_transaction字段后再保存

修改后的views.py代码:

from django.http import HttpResponse
from django.shortcuts import render
from forms import AccountBookingForm
from models import Transaction


def deposit(request):
    context = {}
    if request.method == "POST":
        form = AccountBookingForm(request.POST)
        if form.is_valid():  # 必须先验证表单数据合法性
            t = Transaction.objects.create()  # 创建并保存Transaction到数据库
            booking = form.save(commit=False)  # 获取未保存的AccountBooking实例
            booking.fk_transaction = t
            booking.save()  # 最终保存AccountBooking记录
            return render(request, "deposit_success.html", {"form": form})
    else:
        form = AccountBookingForm()
    return render(request, "deposit.html", {"form": form})

补充说明:

  • 务必调用form.is_valid(),避免因非法数据导致后续保存失败
  • Transaction.objects.create()等价于创建实例后调用save(),写法更简洁
  • commit=False会生成模型实例但不写入数据库,方便补充表单未包含的字段

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 17:21:10