2017-06-06 12 views
0

抽象モデルから継承したすべてのフィールドでnullと空白をtrueに設定します。抽象モデルのヌルフィールド属性と空白フィールド属性をオーバーライドする方法

私の現在の試みは、同様のSOの質問に続きます。 overriding the 'default' attribute on ABCおよびoverriding parent model's attribute、これは可能であると言います。 Pythonコンソールからオブジェクトを初期化するときに、必要な実行時の動作が得られますが、移行ファイルやデータベースには反映されません。

コンテキスト:

私は特定のデータにクライアント固有のオーバーライドを作成することができるようにしたいシステムのモデルを持っています。 -

  • コンクリートSystemOverrideをオーバーライドフィールドを定義 - 「フル」システムのレコードを含む - 部分的にオーバーライドされたレコード
  • 具体的なシステムを含む

    • 抽象BaseSystem:私は、次のモデルを持っています。

    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の空白= TrueがSystemOverideで名前フィールドに追加されていません。

  • 答えて

    0

    これは、クラスののinitでは実行できません。 makemigrationsは決してそれを見ることはありません。あなたはメタクラスレベルでそれを行う必要があります。

    +0

    お返事ありがとうございます。しかし、これを達成するためのいくつかのコードを詳しく説明できますか? –

    +0

    makemigrationsを実行してもinitは実行されません。クラスのインスタンスを作成するときに実行されます。クラスの作成前にクラスの属性を変更する場合は、modelbaseをチェックしてください。 https://github.com/django/django/blob/master/django/db/models/base.py –

    +0

    ご指摘ありがとうございます。私はまだこれを実装する方法を理解するために苦労しています。 'ModelBase .__ new__'に行く前に属性を変更するには、SystemOverrideクラスの' __new __(cls、name、bases、attrs) 'メソッドをオーバーライドする必要がありますか?どんな提案も大歓迎です。ありがとう –

    関連する問題