[英]save upload file to dynamic directory and get the path for store in db
I'm uploading a file and additionally some data like file's id and file's title to the server. 我正在将文件以及文件ID和文件标题之类的一些数据上传到服务器。 I have the view below to handle the request and I want to save the file to a dynamic path like
upload/user_id/thefile.txt
. 我具有下面的视图来处理请求,并且我想将文件保存到动态路径,例如
upload/user_id/thefile.txt
。
With code the below the file will be saved in and upload folder directly and also my product_video
table will create a new record with the related id and the title. 使用下面的代码,该文件将被保存到直接上传文件夹中,并且我的
product_video
表还将创建一个具有相关ID和标题的新记录。
Now I don't have any idea how can I save the file in a dynamically generated directory like: upload/user_id/thefile.txt
and how to save the produced path to the database table column video_path
? 现在我不知道如何将文件保存在动态生成的目录中,例如:
upload/user_id/thefile.txt
以及如何将生成的路径保存到数据库表列video_path
?
view class: 查看类别:
class FileView(APIView):
parser_classes = (MultiPartParser, FormParser)
def post(self, request, *args, **kwargs):
if request.method == 'POST' and request.FILES['file']:
myfile = request.FILES['file']
serilizer = VideoSerializer(data=request.data)
if serilizer.is_valid():
serilizer.save()
fs = FileSystemStorage()
fs.save(myfile.name, myfile)
return Response("ok")
return Response("bad")
and serializer clas: 和序列化器分类:
class VideoSerializer(ModelSerializer):
class Meta:
model = Product_Video
fields = [
'p_id',
'title',
'video_length',
'is_free',
]
and related model class: 和相关模型类:
def user_directory_path(instance, filename):
return 'user_{0}/{1}'.format(instance.user.id, filename)
class Product_Video(models.Model):
p_id = models.ForeignKey(Product, on_delete=models.CASCADE, to_field='product_id', related_name='product_video')
title = models.CharField(max_length=120, null=True,blank=True)
video_path = models.FileField(null=True, upload_to=user_directory_path,storage=FileSystemStorage)
video_length = models.CharField(max_length=20, null=True, blank=True)
is_free = models.BooleanField(default=False)
You put the cart before the horse. 你把车放在马的前面。 Start from the beginning, first things first.
从头开始,首先要做的是。 And the first thing is the user story, then the model layer.
首先是用户故事,然后是模型层。
There are Products and a Product can have many ProductVideos . 有产品 ,一个产品可以有许多ProductVideos 。 A Product has an Author (the Author can have many Products ).
一个产品有一个作者 ( 作者可以有多个产品 )。 When you upload a ProductVideo for a particular Product , you want to save it in a directory which contains the Author ID.
当您上传特定产品的ProductVideo时 ,您要将其保存在包含作者 ID的目录中。
Therefore we specify a callable for the FileField
which should dynamically find out the id
of the Author : 因此,我们为
FileField
指定了一个可调用的对象,该对象应动态找出Author的id
:
def user_directory_path(instance, filename):
# get the id of the author
# first get the Product, then get its author's id
user_id = str(instance.p_id.author.id)
# little bit cosmetics
# should the filename be in uppercase
filename = filename.lower()
return 'user_{0}/{1}'.format(user_id, filename)
When saving an instance of Product_Video
the uploaded file should be stored in a directory with a dynamically created pathname based on the author's ID. 保存
Product_Video
实例时,应将上传的文件存储在目录中,该目录应具有基于作者ID的动态创建的路径名。
Further I'd suggest you to follow established coding conventions: 此外,我建议您遵循既定的编码约定:
snake_case
for class names, especially don't mix it with capital letters. snake_case
用作类名,尤其是不要将其与大写字母混合使用。 Use PascalCase
, preferably singular nouns, for class names: ProductVideo
PascalCase
(最好是单数名词)作为类名: ProductVideo
ProductVideo
, keep that name in all subsequent classes: ProductVideoSerializer
for the model serializer and ProductVideoAPIView
for the generic view. ProductVideo
,保持这个名字在所有后续类: ProductVideoSerializer
为模型串行和ProductVideoAPIView
的通用视图。 get_user_directory
or upload_to_custom_path
is better than user_directory_path
. get_user_directory
或upload_to_custom_path
优于user_directory_path
。 _id
. _id
。 Use rather product
instead of p_id
. product
而不是p_id
。 Django will allow you to access the related object by calling product
and get the id of the object by calling product_id
. product
访问相关对象,并通过调用product_id
获取对象的ID。 Using the name p_id
means you'll access the id of the related object by calling p_id_id
which looks very weird and confusing. p_id
意味着您将通过调用看起来很奇怪和令人困惑的p_id_id
来访问相关对象的ID。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.