如何解决Django-Rest-Framework:如何构建异步目录/文件夹上传和批量文件上传
所以我和我的队友一直在努力解决我们构建的同步文件上传 CRUD 端点的效率问题,现在我们需要使用 celery 或 asyncio(任何欢迎使用其他方法)。
我目前的工作
我的模型:
class CompanyFileUpload(SoftDeletionModel):
name = models.CharField(
max_length=100,null=True,unique=False,blank=True,default="file name"
)
user = models.ForeignKey(
User,on_delete=models.CASCADE,related_name='company_file_uploads'
)
timestamp = models.DateTimeField(
auto_Now_add=True
)
data_file = models.FileField(
upload_to=Utils.create_company_file_upload_path,validators=[validate_file]
)
comment = models.CharField(
max_length=400,unique=False
)
file_size = models.CharField(
max_length=100,default="null"
)
def save(self,*args,**kwargs):
size = self.data_file.size
power = 2**10
n = 0
power_labels = {0: '',1: 'Kilo',2: 'Mega',3: 'Giga',4: 'tera'}
while size > power:
size /= power
n += 1
self.file_size = f"{size:.2f} {power_labels[n]}bytes"
self.name = self.data_file.name
super(CompanyFileUpload,self).save(*args,**kwargs)
def __str__(self):
return f'{self.data_file},{self.user}'
@receiver(post_save,sender=CompanyFileUpload)
def email_report_details_handler(sender,instance,**kwargs):
ctx = {
"firstname": instance.user.firstname,"timestamp": instance.timestamp,"fullname_and_email": f"{instance.user.firstname} {instance.user.othernames}","subject": "File Upload","recepient": instance.user.email,"email": instance.user.email,"url": instance.data_file.url,"comment": instance.comment
}
Utils.send_report_email(ctx)
我的序列化程序:
class CompanyFileUploadSerializer(serializers.ModelSerializer):
timestamp = serializers.DateTimeField(
format="%d-%m-%Y %H:%M:%s",read_only=True)
class Meta:
model = CompanyFileUpload
fields = ["id","name","user","data_file","comment","file_size","timestamp"]
extra_kwargs = {
'file_size': {'read_only': True},'name': {'read_only': True}
}
我的观点:
class CreateCompanyFileUploadAPI(generics.CreateAPIView):
"""
API endpoint for creating a Company file_upload
Sample Response:
{
"id": 3,"user": 4,"title": "This is an awesome file","data_file": "https://{ url_to_some_storage :) }","comment": "Well it should be awesome...","timestamp": "2021-06-09T19:33:04.835268Z"
}
"""
serializer_class = CompanyFileUploadSerializer
class ListCompanyFileUploadsAPI(generics.ListAPIView):
"""
API endpoint for viewing all Company file_uploads
Sample Response:
[
{
"id": 3,"timestamp": "2021-06-09T19:33:04.835268Z"
}
]
"""
serializer_class = CompanyFileUploadSerializer
lookup_field = 'pk'
filter_backends = (SearchFilter,OrderingFilter,DjangoFilterBackend,)
search_fields = ["title","user__firstname"]
def get_queryset(self):
user = self.request.user
return CompanyFileUpload.objects.filter(user=user).order_by("-timestamp")
class RetrieveCompanyFileUploadDetailsAPI(generics.RetrieveAPIView):
"""
API endpoint for reading a Company single file_upload details
Sample Response:
{
"id": 3,"data_file": "https:{ url_to_some_storage :) }","timestamp": "2021-06-09T19:33:04.835268Z"
}
"""
serializer_class = CompanyFileUploadSerializer
lookup_field = 'pk'
def get_queryset(self):
user = self.request.user
return CompanyFileUpload.objects.filter(user=user)
class DeleteCompanyUploadedFileAPI(generics.DestroyAPIView):
"""
API endpoint to delete already uploaded Company files from local/blob storage
"""
serializer_class = CompanyFileUploadSerializer
queryset = CompanyFileUpload.objects
lookup_field = "pk"
def get_queryset(self):
user = self.request.user
return CompanyFileUpload.objects.filter(user=user)
class UpdateCompanyUploadedFileAPI(generics.UpdateAPIView):
"""
API endpoint for updating an uploaded company file details/content
{
"id": 2,"user": 2,"title": "lnlnl","comment": "Changed","file_size": "86.25 Kilobytes","timestamp": "2021-06-21T22:15:20.342044Z"
}
"""
serializer_class = CompanyFileUploadSerializer
queryset = CompanyFileUpload.objects
lookup_field = "pk"
def get_queryset(self):
user = self.request.usclass CreateCompanyFileUploadAPI(generics.CreateAPIView):
"""
API endpoint for creating a Company file_upload
Sample Response:
{
"id": 3,"timestamp": "2021-06-21T22:15:20.342044Z"
}
"""
serializer_class = CompanyFileUploadSerializer
queryset = CompanyFileUpload.objects
lookup_field = "pk"
def get_queryset(self):
user = self.request.user
return CompanyFileUpload.objects.filter(user=user)er
return CompanyFileUpload.objects.filter(user=user)
电子邮件方式:
class Utils:
@staticmethod
def send_report_email(ctx):
"""utility service to handle report upload details email """
message = get_template('mail.html').render(ctx)
msg = EmailMessage(
ctx["subject"],message,os.environ.get("EMAIL_HOST_USER"),[ctx["recepient"]],)
msg.content_subtype = "html" # Main content is Now text/html
msg.send()
我已经使用 docker compose 容器化了 django-app 和 Nginx 服务器。使用天蓝色灯泡容器存储处理存储。
现在,问题是,如何将当前的 FileUpload CRUD 端点转换为批量文件上传(或目录上传)CRUD(至少对于创建端点)? 我尝试解决我在本文中找到的批量序列化程序; Efficient Bulk Create with Django Rest Framework,但尽管我发现将它用于其他端点的 CRUD 取得了一些成功,但到目前为止,我在为 fileUplaod 创建端点实施此方法时不幸失败,如果有人可以向我提供任何建议或可行的方法,我将不胜感激解决方案。
此 Rest-API 适用于企业系统软件,并且非常需要/需要效率。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。