2016-08-17 2 views
0

upload_pathのImageField名を取得する必要があります。
私はのImageField定義で使用partialを試してみました:`makemigrations`コマンドを使うたびにDjangoが新しいマイグレーションファイルを生成するのはなぜですか? upload_path属性が変更されたImageFIeldの場合

class MyModel(models.Model): 

    image = models.ImageField(
     upload_to=partial(image_upload_path, 'image') 
    ) 

今私は、関数の最初の引数で、その文字列を取得できます。

def image_upload_path(field, instance, filename): 
    .... 

すべてが正常に動作しますが、今Djangoは移行ファイルを生成し、その都度Iそれに同じoperationsリストで、makemigrations使用:

operations = [ 
    migrations.AlterField(
     model_name='genericimage', 
     name='image', 
     field=core_apps.generic_image.fields.SorlImageField(upload_to=functools.partial(core_apps.generic_image.path.image_upload_path, *('image',), **{}),), 
    ), 
] 

がたぶんあり他の方法にアクセスするフィールド名upload_pathまたは何らかの形で私の解決策を修正することができますか?

答えて

1

私は自分のフィールドを構築することを決定:移行と

class SorlImageField(ImageField): 

    def __init__(self, verbose_name=None, name=None, width_field=None, 
      height_field=None, lookup_name=None, **kwargs): 
     self.lookup_name = lookup_name 
     kwargs['upload_to'] = partial(image_upload_path, lookup_name) 
     super(SorlImageField, self).__init__(verbose_name, name, 
             width_field, height_field, **kwargs) 

    def deconstruct(self): 
     name, path, args, kwargs = super(SorlImageField, self).deconstruct() 
     del kwargs['upload_to'] 
     # del upload_to will solve migration issue 
     return name, path, args, kwargs 

    def check(self, **kwargs): 
     errors = super(SorlImageField, self).check(**kwargs) 
     if self.lookup_name != self.name: 
      error = [ 
       checks.Error(
       'SorlImageField lookup_name must be equal to ' 
       'field name, now it is: "{}"'.format(self.lookup_name), 
       hint='Add lookup_name in SorlImageField', 
       obj=self, 
       id='fields.E210', 
      )] 
     errors.extend(error) 
    return errors 

問題deconstructメソッドで解決されました。upload_to引数を削除しました。また、フィールド名を指す__init__に追加の引数を追加し、check関数のチェックが正しくlookup_nameの値になっています。そうでない場合、移行が開始されるとエラーが発生します。

class MyModel(models.Model): 

    image = SorlImageField(
     lookup_name='image' 
    ) 
1

この場合は部分的に指定する必要はないようですが、Djangoのドキュメントのthis exampleのような2つのパラメータを使用して呼び出し可能なだけです。

Djangoは、upload_to引数に2つのパラメータ(instancefilename)を指定して呼び出した呼び出し可能コードを呼び出します。

instance

FileFieldには定義されたモデルのインスタンス。具体的には、これは現在のファイルが添付されている特定のインスタンスです。

これはあなたが書く呼び出し可能にinstance.nameのようにインスタンスのnameフィールドにアクセスできることを意味します:

class MyModel(models.Model): 

    name = models.CharField(max_length=255) 
    image = models.ImageField(upload_to=image_upload_path) 


def image_upload_path(instance, filename): 
    # Access the value of the `name` field 
    # of the MyModel instance passed in and save it to a variable: 
    name = instance.name 

    # Code that returns a Unix-style path (with forward slashes) goes here 
+0

インスタンス - ** FileFieldには定義されているモデルのインスタンス.. **、私の場合、それは 'MyModel'ない' ImageField' –

+0

DjangoののImageField [FileFieldにように振る舞う](HTTPSのインスタンスであります://docs.djangoproject.com/ja/1.10/ref/models/fields/#imagefield)にいくつかのオプションがあります。 ImageFieldを 'MyModel'クラスに追加しました。 これはあなたが望むものではありませんか? –

+0

'instance'はModelのインスタンスを返します。ここで' ImageField'は 'image'という名前で定義されています。 'upload_path'にこの' name 'が必要です。とにかく私はカスタムフィールドを書く、私はすぐに答えを更新します。助けてくれてありがとう –

関連する問題