保存对象预操作
保存对象时,对象的某一个字段是通过其他字段计算得到的,如何实现?
1.方式一:重写save()方法。
class Asset(BaseModel):
...
def save(self, *args, **kwargs):
if self.asset_type:
cases = []
for assets_type_choice in Asset.assets_type_choices:
if assets_type_choice[1] not in ATTACHMENTS:
cases.append(assets_type_choice[0])
temp = False
for case in cases:
if case == self.asset_type:
self.is_case = True
temp = True
if not temp:
self.is_case = False
else:
self.is_case = False
return super().save(*args,**kwargs)
2.方式二:pre_save()干预保存,获取预保存信号,进行保存之前处理。
# 任意找个位置
from django.db.models.signals import pre_save
from django.dispatch import receiver
@receiver(pre_save, sender=Asset)
def my_handler(sender, **kwargs):
def is_machine_case(asset_type):
if not asset_type:
return False
cases = []
for assets_type_choice in Asset.assets_type_choices:
if assets_type_choice[1] not in ATTACHMENTS:
cases.append(assets_type_choice[0])
for case in cases:
if case == asset_type:
return True
return False
asset = kwargs['instance']
asset.is_case = is_machine_case(asset.asset_type)
当然 ,有pre_save()方法,相对的就会有post_save()方法, 其中pre_save()方法在save之前执行,post_save()方法在save之后执行。
多对多字段预处理
对于多对多字段(ManyToManyField),save()方法中无法保存,Django专门提供了save_related()方法用于保存多对多关系。该方法在admin.ModelAdmin中,所以想要对多对多字段进行干预或者是保存后获取该字段数据,需要重写save_related()方法。
def save_related(self, request, form, formsets, change):
super().save_related(request, form, formsets, change)
# save方法中无法保存多对多字段,save_related保存多对多关系,此处用来更新PeriodicTask表中的脚本信息。
period_task_obj = PeriodicTask.objects.filter(name=form.instance.job_name).first()
if not period_task_obj:
return None
cli_job = CrontabCliJob.objects.filter(job_name=form.instance.job_name).first()
if cli_job:
parse_script_list = cli_job.parse_scripts.all()
parse_ser = ParserSerializer(parse_script_list, many=True)
task_kwargs = json.dumps({
'job_name': form.instance.job_name,
'device_filter': form.instance.device_filter,
'commands': form.instance.cmds.split(','),
'cmdb_api': form.instance.cmdb_api,
'parse_scripts': json.dumps(parse_ser.data, ensure_ascii=False)
}, ensure_ascii=False)
period_task_obj.kwargs = task_kwargs
period_task_obj.save()