2016-08-17 48 views
0

我需要在upload_path函數中獲取ImageField名稱。
我試過的ImageField定義使用partial爲什麼Django每次使用`makemigrations`命令時都會生成新的遷移文件。對於更改了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的生成遷移文件,每次我它使用makemigrations,同operations名單:

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)就可以調用。

Django將使用2個參數(instancefilename)調用您在upload_to參數中提供的可調用函數。

instance

其中的FileField定義該模型的一個實例。更具體地說,這是特定實例,其中當前文件正在附加

這意味着您可以訪問實例的name場像instance.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/en/1.10/ref/models/fields/#imagefield)與一些額外的選項。 您將一個ImageField添加到「MyModel」類。 這不是你想要的嗎? –

+0

'instance'返回Model的實例,其中定義了名爲'image'的ImageField。我在'upload_path'中需要這個'name'。無論如何,我寫自定義字段,我會盡快更新答案。感謝您嘗試提供幫助 –

相關問題