Wagtail:save()时自动填充StreamField的CharBlock无法持久化
问题解决:StreamField字段修改后无法保存
问题原因
直接修改raw_data后未正确触发字段更新,且当update_fields参数存在时,未将product_details纳入更新字段列表,导致修改无法持久化。另外raw_data是序列化后的原始数据,直接修改它不会自动同步到StreamField的内部状态。
解决方案
方法1:直接操作StreamField的实际内容(推荐)
修改save方法,直接操作self.product_details的Block对象,而非raw_data:
def save(self, *args, **kwargs): if self.auto_update: updated = False # 遍历StreamField中的每个Block for block in self.product_details: # 匹配对应的Block类型(替换为你实际注册的Block名称) if block.block_type == 'product_name_and_url_block': # 检查是否需要修改,避免不必要的更新 if block.value.get('product_snippet_url') != 'Test': block.value['product_snippet_url'] = 'Test' updated = True # 如果有修改,确保update_fields包含product_details字段 if updated and kwargs.get('update_fields'): kwargs['update_fields'] = list(kwargs['update_fields']) + ['product_details'] return super().save(*args, **kwargs)
方法2:修改raw_data后重新赋值
若需基于raw_data修改,必须重新赋值给self.product_details并更新update_fields:
def save(self, *args, **kwargs): if self.auto_update: updated = False # 复制raw_data避免直接修改原对象 new_raw_data = self.product_details.raw_data.copy() for product in new_raw_data: if product['value'].get('product_snippet_url') != 'Test': product['value']['product_snippet_url'] = 'Test' updated = True if updated: # 重新赋值给product_details self.product_details = new_raw_data # 将product_details加入update_fields列表 if kwargs.get('update_fields'): kwargs['update_fields'] = list(kwargs['update_fields']) + ['product_details'] return super().save(*args, **kwargs)
注意事项
- 替换代码中的
product_name_and_url_block为你注册StreamField时使用的Block名称(即StreamField([('xxx', ProductNameAndUrlBlock())])中的xxx) - 实际业务中可把
'Test'替换为你生成的snippet URL
内容的提问来源于stack exchange,提问作者squidg
相关产品推荐
相关产品推荐

