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

如何通过表单集自动将Django模型的updated_by字段填充为登录用户?

解决Django模型表单集自动填充updated_by字段的问题

嘿,很高兴你已经上手模型表单集啦!关于自动把登录用户填充到updated_by字段的需求,我给你两个实用的方案,都是Django项目里常用的做法:

方案一:在视图层直接处理(简单直接)

这种方法适合快速实现,直接在表单集验证通过后,给每个实例手动赋值当前用户:

首先确保视图是登录保护的(避免匿名用户的情况),然后修改视图逻辑:

from django.contrib.auth.decorators import login_required
from django.forms import modelformset_factory
from django.shortcuts import render, redirect
from .models import Inventory

@login_required
def inventory_formset_view(request):
    # 创建表单集,指定需要显示的字段(注意不要包含updated_by)
    InventoryFormSet = modelformset_factory(Inventory, fields=('item', 'stock', 'par'))
    
    if request.method == 'POST':
        formset = InventoryFormSet(request.POST)
        if formset.is_valid():
            # 先获取未保存的实例(commit=False)
            instances = formset.save(commit=False)
            # 循环每个实例,设置updated_by为当前登录用户
            for instance in instances:
                instance.updated_by = request.user
                instance.save()
            # 如果模型有多对多字段,记得调用save_m2m()保存关联
            formset.save_m2m()
            return redirect('your_success_url')  # 替换成你的成功跳转URL
    else:
        formset = InventoryFormSet()
    
    return render(request, 'your_template.html', {'formset': formset})

这个方法的优点是简单直观,不需要修改表单类,适合快速验证需求。

方案二:自定义表单类(更优雅安全)

把字段填充的逻辑封装在表单类里,视图会更简洁,同时能避免前端篡改字段的风险:

第一步:自定义ModelForm

from django import forms
from .models import Inventory

class InventoryForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        # 从初始化参数中取出当前用户
        self.current_user = kwargs.pop('user')
        super().__init__(*args, **kwargs)

    class Meta:
        model = Inventory
        fields = ('item', 'stock', 'par')  # 不包含updated_by,避免前端提交篡改

    def save(self, commit=True):
        # 重写save方法,自动填充updated_by
        instance = super().save(commit=False)
        instance.updated_by = self.current_user
        if commit:
            instance.save()
        return instance

第二步:创建表单集并在视图中使用

from django.contrib.auth.decorators import login_required
from django.forms import modelformset_factory
from django.shortcuts import render, redirect
from .forms import InventoryForm

@login_required
def inventory_formset_view(request):
    # 使用自定义表单创建表单集
    InventoryFormSet = modelformset_factory(Inventory, form=InventoryForm)
    # 传递当前用户给表单的初始化参数
    form_kwargs = {'user': request.user}

    if request.method == 'POST':
        formset = InventoryFormSet(request.POST, form_kwargs=form_kwargs)
        if formset.is_valid():
            formset.save()
            return redirect('your_success_url')
    else:
        formset = InventoryFormSet(form_kwargs=form_kwargs)
    
    return render(request, 'your_template.html', {'formset': formset})

这个方案的好处是把业务逻辑封装在表单类中,视图更简洁,而且因为表单里不包含updated_by字段,前端无法提交该字段的值,安全性更高。

注意事项

  • 一定要用@login_required装饰视图,确保request.user是已登录的有效用户,避免出现IntegrityError(因为updated_by是必填字段)。
  • 如果是编辑已有数据,这两种方案都会自动覆盖原有的updated_by值,符合“更新者为当前用户”的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 20:42:54