我正在上传一个文件,还有一些数据,比如文件的id和文件的标题到服务器。我有以下视图来处理请求,我想将文件保存到动态路径,如upload/user_id/thefile.txt
。
使用以下代码,文件将直接保存在上传文件夹中,我的product_video
表格将创建一个包含相关ID和标题的新记录。
现在我不知道如何将文件保存在动态生成的目录中,如:upload/user_id/thefile.txt
以及如何将生成的路径保存到数据库表列video_path
?
查看课程:
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")
和序列化器clas:
class VideoSerializer(ModelSerializer):
class Meta:
model = Product_Video
fields = [
'p_id',
'title',
'video_length',
'is_free',
]
和相关的模型类:
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)
答案 0 :(得分:1)
你把车放在马前。从头开始,先做好第一件事。首先是用户故事,然后是模型层。
产品,产品可以包含多个 ProductVideos 。 产品有作者(作者可以有多个产品)。当您为特定产品上传 ProductVideo 时,您希望将其保存在包含作者 ID的目录中。
因此,我们为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)
:
Product_Video
保存snake_case
的实例时,上传的文件应存储在具有基于作者ID的动态创建的路径名的目录中。
此外,我建议您遵循既定的编码惯例:
PascalCase
用于类名,尤其不要将其与大写字母混合使用。使用ProductVideo
,最好是单数名词,用于类名:ProductVideo
ProductVideoSerializer
,请在所有后续类中保留该名称:模型序列化程序为ProductVideoAPIView
,通用视图为get_user_directory
。upload_to_custom_path
或user_directory_path
优于_id
。product
为外键字段添加后缀。请使用p_id
代替product
。 Django允许您通过调用product_id
来访问相关对象,并通过调用p_id
来获取对象的ID。使用名称p_id_id
意味着您将通过调用{{1}}来访问相关对象的ID,这看起来非常奇怪且令人困惑。