Django保存对象之前进行预操作

保存对象预操作

保存对象时,对象的某一个字段是通过其他字段计算得到的,如何实现?

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()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值