Python 在对象ID可用后,如何使用DRF修改FileField以采用不同的路径?

Python 在对象ID可用后,如何使用DRF修改FileField以采用不同的路径?,python,django,django-rest-framework,Python,Django,Django Rest Framework,我对DRF文件命名有问题。感兴趣的文件(我相信)是serializers.py。上载文件时,我希望在对象id可用时在upload_to目录中创建一个目录。覆盖create方法很简单。我还没有弄清楚如何更新数据库中的文件以反映新路径。例如,很容易将文件更改为包含所需路径的字符串,但很难将文件更改为具有所需路径的文件 另外,我知道我正在模糊文件关键字。如果有必要,我会换的 # models.py class TestFile(Model): file = FileField(storage

我对DRF文件命名有问题。感兴趣的文件(我相信)是
serializers.py
。上载文件时,我希望在对象id可用时在
upload_to
目录中创建一个目录。覆盖
create
方法很简单。我还没有弄清楚如何更新数据库中的文件以反映新路径。例如,很容易将文件更改为包含所需路径的字符串,但很难将文件更改为具有所需路径的文件

另外,我知道我正在模糊
文件
关键字。如果有必要,我会换的

# 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')

这就是我在
models.py中输入的内容,以解决我的问题。我将
serializers.py
中的相关序列化程序更改为具有默认的create()方法


你能先做obj.file=new_file,然后再做obj.save()?@zaphod100.10吗。
@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()