如何重写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
相关产品推荐
相关产品推荐

