I'm uploading a file and additionally some data like file's id and file's title to the server. 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
.
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.
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
?
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. 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.
Therefore we specify a callable for the
FileField
which should dynamically find out theid
of the Author: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.Further I'd suggest you to follow established coding conventions:
snake_case
for class names, especially don't mix it with capital letters. UsePascalCase
, preferably singular nouns, for class names:ProductVideo
ProductVideo
, keep that name in all subsequent classes:ProductVideoSerializer
for the model serializer andProductVideoAPIView
for the generic view.get_user_directory
orupload_to_custom_path
is better thanuser_directory_path
._id
. Use ratherproduct
instead ofp_id
. Django will allow you to access the related object by callingproduct
and get the id of the object by callingproduct_id
. Using the namep_id
means you'll access the id of the related object by callingp_id_id
which looks very weird and confusing.