Django APIView传递请求数据被修改问题求助
Django中request.data传递后修改导致数据共享的问题解决
问题根源
你遇到的核心问题是浅拷贝导致的嵌套数据引用共享:
Django的request.data(处理JSON请求时通常是dict或QueryDict类型),调用request.copy()只是做了浅拷贝——外层字典是新的,但里面的嵌套对象(比如你的product字典)还是和原数据指向同一个内存地址。所以tinybird方法里执行del product['options'],本质是修改了这个共享的嵌套字典,events方法自然就拿不到options键了。
解决办法
1. 用深拷贝生成完全独立的副本(最稳妥)
直接用Python标准库的copy.deepcopy(),把整个request.data复制成完全独立的两份,这样两个方法操作的是完全不相关的数据:
import copy class EventsView(APIView): def post(self, request): # 生成两个完全独立的深拷贝副本 tinybird_data = copy.deepcopy(request.data) events_data = copy.deepcopy(request.data) self.tinybird(tinybird_data) self.events(events_data) # 后续业务逻辑 def tinybird(self, data): product = data['product'] del product['options'] # 其他操作 def events(self, data): product = data['product'] options = product['options'] # 不会再触发KeyError # 其他操作
2. 手动复制嵌套结构(性能更优,适合固定数据结构)
如果你的数据结构固定,不想用深拷贝(数据量大时深拷贝会有性能开销),可以手动复制嵌套的product字典:
class EventsView(APIView): def post(self, request): original_data = request.data # 分别复制外层字典和嵌套的product tinybird_data = {**original_data, 'product': original_data['product'].copy()} events_data = {**original_data, 'product': original_data['product'].copy()} self.tinybird(tinybird_data) self.events(events_data) # 后续业务逻辑
3. 不修改原数据,生成新字典(更安全的编码习惯)
如果tinybird方法只需要去掉options的版本,没必要删除原键,直接生成新字典即可:
def tinybird(self, data): # 生成不含options的新product字典,不修改原数据 filtered_product = {k: v for k, v in data['product'].items() if k != 'options'} # 用filtered_product做后续操作,原data['product']不受影响
内容的提问来源于stack exchange,提问作者Decoder
相关产品推荐
相关产品推荐

