gpt4 book ai didi

python - 在 django 中上传文件和一些数据的 RESTful 方式

转载 作者:太空宇宙 更新时间:2023-11-03 17:43:37 25 4
gpt4 key购买 nike

我正在使用 django 创建一个 web 服务 django rest framework 。用户可以上传一些图像和视频。上传媒体是一个两步操作,首先用户上传文件并接收 ID,然后在单独的请求中使用该 ID 来引用媒体(例如,他可以将其用作个人资料图片或在聊天消息中使用) )。

我需要知道正在为 HMAC 身份验证中间件上传媒体并在数据库中设置媒体所有者。所有其他请求均采用 JSON 格式,并包含 HMAC 中间件用来检索 secret 共享 key 的 username 字段。

我首先想到媒体上传 api 可能如下所示:

{
"username":"mjafar",
"datetime":"2015-05-08 19:05",
"media_type":"photo",
"media_data": /* base64 encoded image file */
}

但我认为对于较大的文件(例如视频),base64 编码可能会产生显着的开销;或者可以在 json 中解析或在用户端创建的数据大小可能有一些限制。 (这个网络服务应该与 Android/iOS 应用程序通信,它们的内存有限)!这是一个好的解决方案吗?我的担忧是真正的问题还是我不​​应该担心?更好的解决方案?

最佳答案

你可以将两者分开。一个界面上的元数据,带有指向实际文件的 URL。根据您存储实际文件的方式,您可以稍后通过 URL 直接引用该文件。

然后您可以让 POST API 直接接受文件并简单地返回 JSON 元数据

{
"username":"mjafar", // inferred from self.request.user
"datetime":"2015-05-08 19:05", // timestamp on server
"media_type":"photo", // inferred from header content-type?
// auto-generated hashed location for file
"url": "/files/1dde/2ecf/4075/f61b/5a9c/1cec/53e0/ca9b/4b58/c153/09da/f4c1/9e09/4126/271f/fb4e/foo.jpg"
}

使用 DRF 创建这样的接口(interface)将更符合实现 rest_framework.views.APIView 的思路。

这是我为我的一个网站所做的事情:

class UploadedFile(models.Model):
creator = models.ForeignKey(auth_models.User,blank=True)
creation_datetime = models.DateTimeField(blank=True,null=True)
title = models.CharField(max_length=100)
file = models.FileField(max_length=200, upload_to=FileSubpath)
sha256 = models.CharField(max_length=64,db_index=True)
def save(self,*args,**kw_args):
if not self.creation_datetime:
self.creation_datetime = UTC_Now()
super(UploadedFile,self).save(*args,**kw_args)

序列化器:

class UploadedFileSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = UploadedFile
fields = ('url', 'creator','creation_datetime','title','file')

以及使用它的 View :

from rest_framework.views import APIView
from qc_srvr import serializers,models
from rest_framework.response import Response
from rest_framework import status
from rest_framework import parsers
from rest_framework import renderers
import django.contrib.auth.models as auth_models
import hashlib


class UploadFile(APIView):
'''A page for uploading files.'''

throttle_classes = ()
permission_classes = ()
parser_classes = (parsers.FormParser, parsers.JSONParser,)
renderer_classes = (renderers.JSONRenderer,)
serializer_class = serializers.UploadedFileSerializer

def calc_sha256(self,afile):
hasher = hashlib.sha256()
blocksize=65536
hasher.update('af1f9847d67300b996edce88889e358ab81f658ff71d2a2e60046c2976eeebdb') # salt
buf = afile.read(blocksize)
while len(buf) > 0:
hasher.update(buf)
buf = afile.read(blocksize)
return hasher.hexdigest()


def post(self, request):
if not request.user.is_authenticated():
return Response('User is not authenticated.', status=status.HTTP_401_UNAUTHORIZED)

uploaded_file = request.FILES.get('file',None)
if not uploaded_file:
return Response('No upload file was specified.', status=status.HTTP_400_BAD_REQUEST)


# calculate sha
sha256 = self.calc_sha256(uploaded_file)

# does the file already exist?
existing_files = models.UploadedFile.objects.filter(sha256=sha256)
if len(existing_files):
serializer = self.serializer_class(instance=existing_files[0],context={'request':request})
else:
instance = models.UploadedFile.objects.create(
creator = request.user,
title= uploaded_file.name,
file = uploaded_file,
sha256 = sha256)
serializer = self.serializer_class(instance=instance,context={'request':request})
#import rpdb2; rpdb2.start_embedded_debugger('foo')
#serializer.is_valid()
return Response(serializer.data)

仅供引用,这有点隐秘的安全性,因为如果您有文件的 URL,则所有上传的文件都是可检索的。

我仍在使用 DRF 2.4.4,因此这可能不适用于 3+ 版本。由于删除了嵌套序列化器支持,我还没有升级。

关于python - 在 django 中上传文件和一些数据的 RESTful 方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30126720/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com