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

如何在Django表单中加载数据库初始数据供用户更新?

问题:从数据库加载数据到表单时获取到DeferredAttribute而非实际值

我需要从数据库加载数据到表单供用户更新,但当前方法得到的是<django.db.models.query_utils.DeferredAttribute object at 0x000001DB8861EAC0>而非货币值,请问如何在init_supplier字典中放入正确的数据?已尝试在表单中使用__init__方法以及在视图中进行过滤。


相关代码

views.py代码

def supplier_form(request):
    s_data = supplier.objects.all 
    init_supplier = {
        'currency' : supplier.currency
    }
    submitted = False
    if request.method == "POST":
        form = s_form(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/home?submitted=TRUE')
    else:
        sup_form = s_form(initial=init_supplier)
        if submitted in request.GET:
            submitted = True
    return render(request, 'forms/supplier_form.html', {'sup_form':sup_form, 'submitted':submitted, 's_data' : s_data})

models.py代码

class Supplier(models.Model): 
    company_name = models.OneToOneField(User, max_length=120, on_delete=models.DO_NOTHING) 
    currency = models.CharField('Currency', max_length=4)
    legal_form = models.CharField('Legal form', max_length=100, choices=legal_form_options, default='Sole proprietorship')
    accounting_standards = models.CharField('Accounting standards', max_length=100) 
    owner_structure = models.CharField('Owner structure', max_length=100) 
    industry_sector = models.CharField('Industry sector', max_length=100, choices=industry_sector_options, default='Advertising')

解决方案

你当前的问题是直接引用了supplier.currency——这是模型类的字段属性,不是具体实例的数值,所以得到的是DeferredAttribute对象。要解决这个问题,核心是获取具体的Supplier实例,再提取它的currency值。

步骤1:获取目标Supplier实例

因为你的Supplier和User是一对一关系,通常是加载当前登录用户对应的Supplier数据:

try:
    # 通过当前登录用户关联获取Supplier实例
    supplier_instance = Supplier.objects.get(company_name=request.user)
except Supplier.DoesNotExist:
    # 处理用户没有对应Supplier的情况,比如跳转到创建页面
    return HttpResponseRedirect('/create-supplier')

步骤2:用实例数据填充init_supplier

init_supplier = {
    'currency': supplier_instance.currency
}

修正后的完整views.py代码

def supplier_form(request):
    # 先校验用户是否登录
    if not request.user.is_authenticated:
        return HttpResponseRedirect('/login')
    
    # 获取当前用户对应的Supplier实例
    try:
        supplier_instance = Supplier.objects.get(company_name=request.user)
    except Supplier.DoesNotExist:
        return HttpResponseRedirect('/create-supplier')
    
    init_supplier = {
        'currency': supplier_instance.currency
    }
    submitted = False
    
    if request.method == "POST":
        # 绑定实例到表单,提交时会直接更新该实例而非创建新数据
        form = s_form(request.POST, instance=supplier_instance)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/home?submitted=TRUE')
    else:
        # 传入instance参数后,表单会自动加载实例的所有字段数据,initial可以省略
        sup_form = s_form(instance=supplier_instance)
        if 'submitted' in request.GET:
            submitted = True
    
    # 修正原代码的语法错误:objects.all需要加括号
    s_data = Supplier.objects.all()
    return render(request, 'forms/supplier_form.html', {'sup_form':sup_form, 'submitted':submitted, 's_data' : s_data})

额外提示

  • 模型类名遵循Python规范应该用大驼峰Supplier,你原代码里的小写supplier容易混淆类和实例,建议统一修正。
  • 表单更新时直接传入instance参数是更简洁的方式,不需要手动编写initial字典,表单会自动加载实例的所有字段值。

内容的提问来源于stack exchange,提问作者Piotr Połetek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 16:02:39