2012-03-05 12 views
1

Djangoカスタムモデルフィールドでモデルインスタンスの属性を設定します。モデルフィールドからのモデルインスタンスへのアクセス

私はそれがこのように働いたが、ここでの例ではありませんだと確信しています:

class MyField(models.Field): 
    __metaclass__ = models.SubfieldBase 
    def __init__(self, *args, **kwargs): 
     super(MyField, self).__init__(*args, **kwargs) 
     model_instance = ???? 
     setattr(model_instance, "extra_attribute", "It's working!") 

class MyModel(models.Model): 
    my_field = MyField() 

model_instance = MyModel.objects.get(pk=123) 
print model_instance.extra_attribute # output: "It's working!" 

DjangoのForeignKeyのモデルフィールドは、同じようなことをやっているので、それが可能である:P 私はForeignKeyのフィールドを使用していると思いますcontrib_to_classメソッド。

答えて

-2

Djangoはモデルクラスを処理するときにいかが

model_instance = SomeExtraModel.objects.get(pk=1456) 

が意味

+0

いいえ、 –

+0

フィールドにpk値を渡すにはどうすればいいですか? –

-1

のinitを作る何かを1456を交換していないモデルインスタンス、と呼ばれています。したがって、モデルクラスに属性を追加することができます(たとえば、 'add_to_class' http://www.alrond.com/en/2008/may/03/monkey-patching-in-django/を使用して)。インスタンスに属性を追加するには、インスタンスのinitを上書きする必要があります(ただし、これはあなたのケースではないと思います)。

+0

いいえ、initはオブジェクト構築の最後のステップとして呼び出されます。 – Marcin

+0

@Marcin:ありがとう、私はおそらく実際の流れを誤解しています。あなたはそれについていくつかの文書を投稿できますか? – Don

+0

あなたの国でGoogleを持っていませんか? – Marcin

0

Fieldオブジェクト内からモデルインスタンスにアクセスすることはできません。ごめんなさい。 DjangoのForeignKeyは、別のnameattnameのフィールドを持つことでfoo_idの処理を実行しますが、foo_id = 123の実際の設定は、他のすべてのモデルフィールドのフィールドと同様に行われます。deep in the QuerySet code

概念的に、あなたがしようとしているのは悪いアイデアです。特定のフィールドを追加すると、別のフィールドが予期していた属性がオーバーライドされた場合、関連のないモデル機能にバグが発生する可能性がある場合はどうすればよいでしょうか?デバッグするのは難しいでしょう。あなたの基本的な目標は何か分かりませんが、おそらくフィールドクラスではなくモデルコードで行うべきです。

はここで何をしたいんModelFieldです:

https://gist.github.com/1987190

実際にはかなり古いですそれ(多分前1.0のように、今覚えていない)、少しそれをほこりしなければならなかった - 私は」それがまだ動作するかどうかわからない。しかし、それは間違いなく実行可能です、希望どおりにこれはあなたにアイデアを提供します。

+0

私はどのモデル(GenericForeignKeyのようなものですが、1つのフィールド)との関係をサポートするフィールドを作ろうとしています。 "%d。%d"%(model_type、instance.pk)をcharfieldに保存します。フィールドのattnameは "%s_guid"%name(= model_instance.my_field_guid)になります。 model_instance.my_fieldが呼び出されると(Foreignkeyがやっているように)、DBにヒットして関連するインスタンスを提供したいと思います。ありがとうございます –

+0

ああ、それは簡単です:)。私はあなたが任意の他のフィールドを設定することを意味すると思った私は座っている "ModelField"の例を更新します。 – AdamKG

+0

= Dは素晴らしいです! –

0

フィールドを置き換える特殊なプロキシクラスを作成できます。フィールド値を取得または設定するときは、 'obj'属性を使用してモデルインスタンスにアクセスできます。この例を参照してください:

class ObjectField(models.PositiveSmallIntegerField): 
    class ObjectProxy: 
     def __init__(self, field): 
      self.field = field 

     def __get__(self, obj, model): 
      if obj is None: 
       return self.field # this is required for initializing model field 

      value = obj.__dict__[self.field.name] # get actual field value 
      # ... here you can do something with value and model instance ("obj") 

      return value 

     def __set__(self, obj, value): 
      # same here 
      obj.__dict__[self.field.name] = value 

    def contribute_to_class(self, cls, name): 
     super().contribute_to_class(cls, name) 
     # set up our proxy instead of usual field 
     setattr(cls, name, ObjectField.ObjectProxy(self)) 
関連する問題