I am writing an API that allows the client to post a link to a file, and then I want to download the file and store it as a FileField on one of my models. Here is the code I have so far:
Serializer:
from rest_framework import serializers
from django.core.files import File
from rest_framework.serializers import ValidationError
class MySerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = ('url')
def to_internal_value(self, data):
validated = dict()
url = data.get('url')
# do url validation here
# download the file to local disk
validated['file'] = File(open('path/to/downloaded/file'))
validated['url'] = url
return validated
Model:
from django.db import models
class MyModel(models.Model):
url = models.CharField(max_length=255)
file = models.FileField(upload_to='files/')
For the view, I use a generic ListCreateAPIView.
There are two main problems, first is that with my current implementation, I end up with two copies of the file because I download it to some location on disk first, and then later when the FileField is stored into the database it copies the file again to the files/ folder. Is there some way to avoid this? Secondly, how can I download the file asynchronously yet still be able to add the FileField attribute on the model after the download has completed?