如何使用Django将request获取的文件上传至Google Drive
解决Django表单文件上传至Google Drive的问题
你的代码里有几个关键问题,修正后就能正常完成上传:
- Credentials构建错误:不能直接把SocialAuth对象传给Credentials,得用用户的OAuth2令牌信息来构建合法的认证对象
- 文件名设置错误:
tfile是Django的UploadedFile对象,要取它的name属性作为Drive里的文件名 - 文件夹查询逻辑错误:
user是SocialAuth实例,不是用户的username,应该关联到对应的User对象;另外用[0]容易触发索引越界,换成first()更安全 - MIME类型硬编码:固定成
image/jpeg会导致非图片文件上传失败,直接用上传文件的content_type属性即可
修正后的完整代码:
from googleapiclient.discovery import build from googleapiclient.http import MediaFileUpload from google.oauth2.credentials import Credentials from django.conf import settings # 获取用户的Google OAuth2认证信息 social_auth = request.user.social_auth.get(provider='google-oauth2') tfile = request.FILES['file'] # 构建正确的Credentials对象 credentials = Credentials( token=social_auth.extra_data['access_token'], refresh_token=social_auth.extra_data['refresh_token'], client_id=settings.GOOGLE_OAUTH2_CLIENT_ID, client_secret=settings.GOOGLE_OAUTH2_CLIENT_SECRET, token_uri='https://oauth2.googleapis.com/token' ) drive = build('drive', 'v3', credentials=credentials) # 修正元数据:文件名取上传文件的name,文件夹查询关联User对象 media_metadata = { 'name': tfile.name, 'parents': [folder.objects.filter(user=social_auth.user).first().id_folder] } # 使用文件实际的MIME类型 media = MediaFileUpload(tfile, mimetype=tfile.content_type) # 执行上传 upfile = drive.files().create( body=media_metadata, media_body=media, fields='id' ).execute()
额外注意事项:
- 确保你的
folder模型里的user字段关联的是Django的User模型,而非SocialAuth实例 - 如果需要处理大文件,建议用
MediaIoBaseUpload代替MediaFileUpload,支持流式上传避免内存溢出 - 建议添加异常捕获,比如文件夹不存在、令牌过期等情况,避免程序崩溃
内容的提问来源于stack exchange,提问作者Try To Up
相关产品推荐
相关产品推荐

