You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django模型save()方法递归调用问题求助

问题分析与解决:Yandex磁盘下载递归调用导致报错

问题描述

控制台循环输出日志后报错,控制台显示的download_url看似有效,但代码无法正常运行。疑似save方法发生递归调用,直至Yandex返回“Resource not found”拦截下载。

相关截图:
控制台日志
自定义save方法代码

原代码

def save(self, *args, **kwargs):  # Сначала сохраняем объект

    if self.photo_url:
        base_url = 'https://cloud-api.yandex.net/v1/disk/public/resources/download?'
        public_key = 'https://disk.yandex.ru/i/EaosKvCf-SDzag' #self.photo_url  # Используем поле photo_url как public_key

        final_url = base_url + urlencode(dict(public_key=public_key))
        print(final_url)
        response = requests.get(final_url)
        print(response.json())
        download_url = response.json()['href']
        print(download_url)

        download_response = requests.get(download_url)
        file_content = download_response.content

        file_name = self.photo_url.split('/')[-1]
        temp_file = File(io.BytesIO(file_content), name=file_name)
        self.photo.save(file_name, temp_file, save=False)
        self.save()  # Сохраняем с обновл

    super().save(*args, **kwargs)

问题根源

无限递归调用:
在save方法内部,当self.photo_url存在时,执行完图片保存逻辑后手动调用了self.save(),这会再次触发当前的save方法,形成无限循环。每次递归都会向Yandex发送请求,频繁请求后被Yandex拦截,返回“Resource not found”。

解决方法

  1. 移除手动调用的self.save(),方法末尾的super().save(*args, **kwargs)已经会完成对象的持久化操作。
  2. 添加异常处理,避免API请求失败导致整个保存流程中断。

修改后的代码

def save(self, *args, **kwargs):
    if self.photo_url:
        base_url = 'https://cloud-api.yandex.net/v1/disk/public/resources/download?'
        public_key = 'https://disk.yandex.ru/i/EaosKvCf-SDzag'  # 后续可根据需求改回self.photo_url

        try:
            final_url = base_url + urlencode(dict(public_key=public_key))
            response = requests.get(final_url)
            response.raise_for_status()  # 检查请求是否成功
            download_url = response.json()['href']
            
            download_response = requests.get(download_url)
            download_response.raise_for_status()
            file_content = download_response.content

            file_name = self.photo_url.split('/')[-1]
            temp_file = File(io.BytesIO(file_content), name=file_name)
            self.photo.save(file_name, temp_file, save=False)
        except (requests.exceptions.RequestException, KeyError) as e:
            # 可添加日志记录或自定义错误处理逻辑
            print(f"图片下载/处理失败: {str(e)}")
            # 此处选择继续执行对象保存,可根据需求调整
    super().save(*args, **kwargs)

内容的提问来源于stack exchange,提问作者Bte Deni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 08:52:47