0

私は次のクラスを持っています:

class VideoFile(models.Model):
    media_file = models.FileField(upload_to=update_filename, null=True)

また、次のリクエストを使用して大きなファイル(100mbから2Gbまで)をアップロードしようとすると、アップロードプロセスの後、およびプロセス中にかなり長い時間がかかる可能性がありVideoFile.save()ます。

def upload(request):
    video_file = VideoFile.objects.create(uploader=request.user.profile)
    video_file.media_file = uploaded_file
    video_file.save()

私のMacbookProCore i7、8Gb RAMでは、300mbのアップロードされたファイルの実行に約20秒かかる場合がありますvideo_file.save()

/tmpこの遅延は、ファイルの永続的な場所へのディスクコピー操作に関連していると思われますか?watch ls -lターゲットディレクトリで実行することでこれを証明しました。実行するとすぐvideo_file.save()に、ファイルが表示され、遅延全体で大きくなることがわかります。

このファイル転送の遅延をなくす方法はありますか?ファイルをターゲットファイル名に直接アップロードするか、コピーする代わりに元のファイルを移動するだけですか?ただし、サイト全体でのアップロード操作はこれだけではないため、ソリューションをこのモデルにローカライズする必要があります。

アドバイスありがとうございます!

アップデート:

移動ではなくコピーをサポートするためのさらなる証拠です。アップロード中に、アップロードの進行状況に正確に対応するpythonから書き込まれwatch lsofたファイルを確認できます。/private/var/folders/...アップロードが完了すると、時間の経過とともに大きくなる最終的なファイルの場所を示す別のlsofエントリが表示されます。それが完了すると、両方のエントリが消えます。

4

2 に答える 2

1

/tmpアップロードしてからオーバーすることがベストプラクティスである理由はかなりcpたくさんあり、大きなファイルをターゲットに直接アップロードすることは潜在的に危険な操作であることに注意してください。

しかし、あなたが求めていることは絶対に可能です。Djangoはアップロードハンドラーを定義します:

Djangoがファイルを処理する方法をカスタマイズするカスタムハンドラーを作成できます。たとえば、カスタムハンドラーを使用して、ユーザーレベルの割り当てを適用したり、データをその場で圧縮したり、進行状況バーをレンダリングしたり、データをローカルに保存せずに別の保存場所に直接送信したりすることもできます

于 2013-02-21T21:14:50.273 に答える
1

少し掘り下げた後、私は解決策を思いつきました。Djangoのデフォルトのストレージは、コピーではなくファイルを移動しようとしていることがわかりました。これは最初にテストされます。

hasattr(content, 'temporary_file_path')

この属性TemporaryUploadedFileは、アップロードビューに返されるオブジェクトであるクラスに存在しますが、フィールド自体は、によって指定されたクラスとして作成されます。FileField.attr_class

そこで、代わりに、属性をサブクラスFieldFile化しFileFieldてスロットに入れることにしました。temporary_file_path

class VideoFieldFile(FieldFile):
    _temporary_file_path = None
    def temporary_file_path(self):
        return self._temporary_file_path


class VideoFileField(FileField):
    attr_class = VideoFieldFile

最後に、ビューで、モデルを保存する前に、一時パスを手動で割り当てました。

video_file.media_file._temporary_file_path = uploaded_file.temporary_file_path()

これは、1.1Gbのテストファイルが、以前見ていた50秒ほどではなく、約2〜3秒で利用可能になることを意味します。また、ファイルが異なるファイルシステムに存在する場合、コピー操作にフォールバックしているように見えるという追加の利点もあります。

ただし、私のサイトでは、MemoryFileUploadHandler一部のサイトが小さなファイルのアップロードを処理するために使用する可能性のあるものを利用していないため、私のソリューションがそれでどれほどうまく機能するかはわかりませんが、アップロードされたファイルのクラスとそれに応じて動作します。

于 2013-02-25T08:18:49.327 に答える