4

アップロードされたファイルを処理するための抽象モデルクラスUploadItemがあります。各サブクラスがupload_toパスを定義できるようにしたい。このために、FileFieldのコンストラクターにコールバックを渡します。

これは例です:

class UploadItem(models.Model):
    file = models.FileField(upload_to=UploadItem.get_directory) 


    class Meta:
        abstract = True
# I want videos to be storred in 'videos/' directory
class Video(UploadItem):
    def get_directory(self, instance, filename):
        return 'videos/'

しかし、これは機能しません、私はこのエラーを受け取ります:

file = models.FileField(upload_to=UploadItem.get_directory) 
NameError: name 'UploadItem' is not defined
4

2 に答える 2

6

評価時にエラーが発生するのは当然のことです。

file = models.FileField(upload_to=UploadItem.get_directory) 

UploadItemクラスはまだ定義されていません。あなたはそれを機能させるために以下を行うことができます:

def get_directory():
    pass

class UploadItem(models.Model):
    file = models.FileField(upload_to=get_directory)

    class Meta:
        abstract = True

ただし、これですべての問題が解決するわけではありません。クラスにメソッドget_directoryを追加(またはオーバーライド)しても、モデルの属性のプロパティは変更されません。Videoupload_tofile

アップデート

ドキュメントには、upload_toが呼び出し可能である可能性があると記載されています。

これは、ファイル名を含むアップロードパスを取得するために呼び出される関数などの呼び出し可能である場合もあります。この呼び出し可能オブジェクトは、2つの引数を受け入れ、ストレージシステムに渡されるUnixスタイルのパス(スラッシュ付き)を返すことができる必要があります。

これを前提として、次のようなカスタムコールバック関数を記述できます。

categories_and_paths = { 'video': 'videos/', 'photo': 'photos/' } # etc.
def get_directory(instance, filename):
    category = instance.category
    return categories_and_paths.get(category, '')

Instanceここに、それぞれのモデルのインスタンスがあります。これを機能させるには、各モデルインスタンスにカテゴリフィールドが必要です。モデルの本体に1つ追加できます。

class Video(UploadItem):
    category = 'video'
于 2010-09-08T16:45:58.700 に答える
5

これは、サブクラスの一部として基本クラスのプロパティを使用する必要がある場合に、いくつかの調整を加えて同様の方法で行うことができます。

import os

# ...

def get_directory(instance, filename):
    return instance.get_file_directory(filename)


class UploadItem(models.Model):
    FILE_DIRECTORY = 'files/'

    file = models.FileField(upload_to=get_directory) 

    class Meta:
        abstract = True

    @staticmethod
    def get_file_directory(filename):
        return os.path.join(UploadItem.FILE_DIRECTORY, filename)

そしてサブクラスで:

class Video(UploadItem):
    FILE_DIRECTORY = 'videos/'

    def get_file_directory(self, filename):
        filename = os.path.join(self.FILE_DIRECTORY, filename)
        return super().get_document_path(filename)

このようにして、次のようupload_toになります。

  • filesにとってUploadItem
  • files/videosにとってVideo

いくつかの共通のベースプロパティを共有する必要がある、より複雑なオブジェクトに役立つ場合があります。

于 2016-12-26T14:24:58.400 に答える