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

如何重写Django Admin的save_model批量创建AvailableHours对象?

Django Admin重写save_model实现批量创建AvailableHours对象

现有模型与已实现的ModelForm功能

AvailableHours模型

class AvailableHours(models.Model):
    free_date = models.ForeignKey(AvailableDates,null=True, blank=True,on_delete=models.CASCADE,related_name='freedate')
    free_hours_from = models.IntegerField(null=True, blank=True)
    free_hours_to = models.IntegerField(null=True, blank=True,)
    status = models.BooleanField(null=True,default=True,)

已实现的批量创建ModelForm

通过重写save方法,当输入free_hours_from和free_hours_to时,自动生成每小时一段的AvailableHours对象:

class TimeGenerator(forms.ModelForm):
    class Meta:
        model = AvailableHours
        fields = ['free_date','free_hours_from','free_hours_to','status']  

    def save(self, commit=True):
        base_item = super().save(commit=False)
        frm = self.cleaned_data['free_hours_from']
        to = self.cleaned_data['free_hours_to']
        items = [
            AvailableHours(
                free_date=base_item.free_date,
                status=base_item.status,
                free_hours_from=hour,
                free_hours_to=hour + 1,
            )
            for hour in range(frm, to)
        ]
        if commit:
            AvailableHours.objects.bulk_create(items)
        return items

问题:Admin中重写save_model无效

尝试的Admin代码如下,但无法实现批量创建功能:

class AvailableHoursAdmin(admin.ModelAdmin):
    def save_model(self, commit=True):
        base_item = super().save(commit=False)
        frm = self.cleaned_data['free_hours_from']
        to = self.cleaned_data['free_hours_to']
        items = [
            AvailableHours(
                free_date=base_item.free_date,
                status=base_item.status,
                free_hours_from=hour,
                free_hours_to=hour + 1,
            )
            for hour in range(frm, to)
        ]
        if commit:
            AvailableHours.objects.bulk_create(items)
        return items
admin.site.register(AvailableHours,AvailableHoursAdmin)

解决方案

错误核心是save_model方法签名错误,且未正确利用Admin传递的表单数据。正确实现如下:

class AvailableHoursAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        # 从表单获取清理后的数据
        frm = form.cleaned_data['free_hours_from']
        to = form.cleaned_data['free_hours_to']
        
        # 生成批量对象列表
        items = [
            AvailableHours(
                free_date=form.cleaned_data['free_date'],
                status=form.cleaned_data['status'],
                free_hours_from=hour,
                free_hours_to=hour + 1,
            )
            for hour in range(frm, to)
        ]
        
        # 批量创建对象
        if items:
            AvailableHours.objects.bulk_create(items)
        # 跳过默认的单对象保存,避免创建多余的原始对象
        return

admin.site.register(AvailableHours, AvailableHoursAdmin)

关键修正点:

  • 遵循save_model的正确方法签名:def save_model(self, request, obj, form, change):,通过form参数获取提交的表单数据
  • 直接从form.cleaned_data中读取字段值,替代错误的super().save(commit=False)调用
  • 跳过默认的父类save_model执行,避免生成用户提交的原始无效对象(如13-16的跨3小时对象)
  • 增加if items:判断,防止在frm >= to时执行无意义的批量创建

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 19:20:04