2017-06-06 109 views
0

我想在從抽象模型繼承的所有字段上設置null和空白爲true。如何覆蓋抽象模型的空白字段屬性

我目前的嘗試遵循類似的SO問題,例如, overriding the 'default' attribute on ABCoverriding parent model's attribute,這是可能的。當從python控制檯初始化對象時,我會得到所需的運行時行爲,但它不會反映在遷移文件或數據庫中。

語境:

我有,我希望能夠創造對某些數據的客戶端特定的覆蓋系統模型。我有以下型號:

  • 抽象BaseSystem - 定義可覆蓋領域
  • 混凝土SystemOverride - 包含部分重寫記錄
  • 混凝土系統 - 包含了「全」系統記錄。

使SystemOverride中的所有字段爲null/blank = True是很重要的,這樣只有被客戶端初始化的字段纔會覆蓋相關的System對象。

代碼:

class BaseSystem(models.Model): 

    class Meta: 
     abstract = True 

    def __init__(self, *args, **kwargs): 
     super(BaseSystem, self).__init__(args, kwargs) 

     # Mark all fields with 'override' attribute 
     for field in self._meta.get_fields(): 
      field.override = True 

    name = models.CharField(max_length=128) 


class System(BaseSystem): 
    pass 


class SystemOverride(BaseSystem): 

    def __init__(self, *args, **kwargs): 
     super(SystemOverride, self).__init__(args, kwargs) 

     # Set all overridable fields to null/blank = True. 
     for field in self._meta.get_fields(): 
      if(hasattr(field, 'override') and field.override): 
       field.null = True 
       field.blank = True 

    # Override-specific fields 
    system = models.ForeignKey(System) 

makemigrations結果:

class Migration(migrations.Migration): 

    initial = True 

    dependencies = [ 
    ] 

    operations = [ 
     migrations.CreateModel(
      name='System', 
      fields=[ 
       ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 
       ('name', models.CharField(max_length=128)), 
      ], 
      options={ 
       'abstract': False, 
      }, 
     ), 
     migrations.CreateModel(
      name='SystemOverride', 
      fields=[ 
       ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 
       ('name', models.CharField(max_length=128)), 
       ('system', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='overide.System')), 
      ], 
      options={ 
       'abstract': False, 
      }, 
     ), 
    ] 

空= True和空白=真還沒有被添加到名稱字段SystemOveride。

回答

0

這不能在該類的init中完成。 makemigrations永遠不會看到它。你需要在元類級別上完成它。

+0

感謝您的答案,但你可以詳細闡述/顯示一些代碼,以實現這一目標? –

+0

當您執行makemigrations時,您的init不會運行。它在您創建類的實例時運行。如果要在創建類之前修改類的屬性,請檢查modelbase。 https://github.com/django/django/blob/master/django/db/models/base.py –

+0

感謝您指出。我仍然在努力弄清楚如何實現這一點。我是否需要重寫SystemOverride類上的'__new __(cls,name,bases,attrs)'方法,以在屬性進入'ModelBase .__ new__'之前修改它們?任何建議將不勝感激。謝謝 –