我遇到DRF文件命名问题。感兴趣的文件(我相信)是serializers.py
。当我上传文件时,我想要发生的是当对象的id可用时在upload_to
目录中创建目录。这很容易覆盖create
方法。我还没弄清楚如何更新数据库中的文件以反映新路径。例如,很容易将文件更改为包含所需路径的字符串,但很难将文件更改为具有所需路径的文件。
P.S。我知道我模糊了file
关键字。如有必要,我会改变它。
# models.py
class TestFile(Model):
file = FileField(storage=FileSystemStorage(location=settings.MEDIA_ROOT), upload_to='files', default='{}/files/empty.zip'.format(settings.MEDIA_ROOT))
created_at = CreationDateTimeField()
updated_at = ModificationDateTimeField()
def __str__(self):
return ''.join([str(self.file)])
def __unicode__(self):
return unicode(' '.join([str(self.id)]))
def __id__(self):
return str(self.id)
class Meta:
managed = True
db_table = 'test_files'
verbose_name_plural = 'Test Files'
# viewsets.py
class TestFileViewSet(ModelViewSet):
queryset = TestFile.objects.all()
serializer_class = TestFileSerializer
parser_classes = (MultiPartParser, FormParser)
def perform_create(self, serializer):
serializer.save(file=self.request.data.get('file')
# serializers.py
class TestFileSerializer(ModelSerializer):
file = serializers.FileField(required=True)
def create(self, validated_data):
# Calling create(), this will create the object in the database, making the ID and PK of obj
# available to me.
obj = TestFile.objects.create(**validated_data)
# Creating a new path so that I can use a detail_route in viewset later to GET file
new_path = '/'.join ([str(obj.file).split('/')[0],
str(obj.id),
str(obj.file).split('/')[1]])
# Try to create the parent directory of our destination. This shouldn't fail
try:
os.mkdir(settings.MEDIA_ROOT+ '/files/' +str(obj.id), 0755 )
except:
pass
# Move old file to the new path that we just created.
shutil.copyfile(settings.MEDIA_ROOT + str(obj.file), settings.MEDIA_ROOT + new_path)
# Remove the old file after we have already copied it to new destination
os.rmdir(settings.MEDIA_ROOT + str(obj.file))
# This is where the next step goes!
# What do I need to put in here to make obj.file the correct path now?
return obj
class Meta:
model = TestFile
fields = ( 'id','file','created_at','updated_at')
答案 0 :(得分:0)
这是我在models.py
中提出的解决问题的方法。我在serializers.py
中更改了相关的序列化程序,以使用默认的create()方法。
@python_2_unicode_compatible
class TestFile(models.Model):
file = models.FileField(storage=FileSystemStorage(location=settings.MEDIA_ROOT),
upload_to='files/temporary_storage',
blank=True)
created_at = CreationDateTimeField()
updated_at = ModificationDateTimeField()
def save(self, *args, **kwargs):
super(TestFile, self).save(*args, **kwargs)
def __str__(self):
return ' '.join([str(self.file)])
def __unicode__(self):
return unicode(' '.join([str(self.id)]))
def __id__(self):
return str(self.id)
class Meta:
managed = True
db_table = 'test_file'
verbose_name_plural = 'Test Files'
@receiver(post_save, sender=TestFile, dispatch_uid="update_filefield")
def update_file(sender, instance, **kwargs):
filefield = instance.file
if filefield:
filename = filefield.name
new_file_path = ''
if "temporary_storage" in filename:
tmp = filename.split("temporary_storage", 1)
new_file_path = "{}{}{}".format(tmp[0], str(instance.pk), tmp[1])
if new_file_path != filename:
instance.file.storage.delete(new_file_path)
instance.file.storage.save(new_file_path, filefield)
instance.file.name = new_file_path
instance.file.close()
instance.file.storage.delete(filename)
instance.save()