Django后台上传文件路径获取异常:无法上传至Supabase
Django admin上传文件到Supabase报错「文件不存在」的解决办法
你代码里的几个致命问题:
- 模型字段用错了:模型里应该用
models.FileField,你写成了forms.FileField——后者是给表单用的,模型不认这个。 - 文件路径拿早了:在
save方法执行时,Django还没把上传的文件写到本地磁盘,self.video.path此时根本不存在,自然会提示找不到文件。 - 用户登录逻辑完全错误:Django存的是密码哈希,不是明文,你用
self.user.password去调用Supabase的登录接口,肯定登不上,而且这种做法极度不安全。
修正后的完整代码
from django.db import models from supabase import create_client import os class PupinObject(models.Model): # 把forms.FileField改成models.FileField video = models.FileField(upload_to='videos/') creation_date = models.DateTimeField(auto_now_add=True) user = models.ForeignKey(PupinUser, on_delete=models.CASCADE) # 可选:加个字段存Supabase的文件链接 supabase_video_url = models.URLField(null=True, blank=True) def save(self, *args, **kwargs): # 用Supabase的服务端密钥,不用用户密码登录 supabase_url = os.environ.get("SUPABASE_URL") supabase_service_key = os.environ.get("SUPABASE_SERVICE_ROLE_KEY") supabase = create_client(supabase_url, supabase_service_key) bucket_name = "videos" # 按用户ID组织文件路径 target_path = f"/{self.user.id}/video.mp4" # 直接读取上传文件的二进制流,不用本地路径 with self.video.open('rb') as file_stream: supabase.storage.from_(bucket_name).upload(target_path, file_stream) # 获取文件的公开访问链接(前提是Supabase的videos bucket设为公开) self.supabase_video_url = supabase.storage.from_(bucket_name).get_public_url(target_path) # 要是不想把文件存在本地,可以把video字段置空 # self.video = None # 最后调用父类的save方法 super().save(*args, **kwargs)
额外注意事项:
- 服务端密钥获取:去Supabase控制台的「设置」→「API」页面,找
service_role类型的密钥,把它加到你的环境变量里,别泄露这个密钥。 - Bucket权限设置:如果要让上传的文件能公开访问,得在Supabase存储控制台把
videosbucket的权限改成「公开」;要是需要私密访问,就得生成带签名的临时URL。 - 本地存储取舍:如果不需要在本地保留文件,可以修改Django的默认存储后端为Supabase,或者在上传后清空
video字段,避免占用服务器空间。
内容的提问来源于stack exchange,提问作者ogi-joo
相关产品推荐
相关产品推荐

