2016-08-25 8 views
3

私は以下のような状況に陥っています
フィールドに応じてクエリーセットをフィルタリングするマネージャクラスがあります。問題は、フィールド名はクラスによって異なりますが、フィルタリングする値は同じ場所から来ている(私はいくつかのマネージャーが必要ないと思ったので)。これは私がこれまで行ったことです。パラメータを使ってDjangoマネージャを作成する

class MyManager(models.Manager): 
    def __init__(self, field_name): 
     super(MyManager, self).__init__() 
     self.field_name = field_name 

    def get_queryset(self): 
     # getting some value 
     kwargs = { self.field_name: some_value } 
     return super(MyManager, self).get_queryset().filter(**kwargs) 

class A: 
    # some datamembers 

    @property 
    def children(self): 
     return MyUtils.prepare(self.b_set.all()) 

class B: 
    objects = MyManager(field_name='my_field_name') 
    a = models.ForeignKey(A, null=False, blank=False) 

私がDBからBオブジェクトを取得テストIを実行し、私は次のエラーを取得childrenプロパティの読み取りしようとすると:

self = <django.db.models.fields.related_descriptors.RelatedManager object at 0x7f384d199290>, instance = <A: A object> 

    def __init__(self, instance): 
>  super(RelatedManager, self).__init__() 
E  TypeError: __init__() takes exactly 2 arguments (1 given) 

を私が知っているそのため、コンストラクタのパラメータのため、私がそれを削除する(またはデフォルト値を与える)と、すべてのテストが機能します。
どうすればこの問題を解決できますか?これはこれを達成する正しい方法ですか?
テックのもの:

  1. ジャンゴ1.9.5
  2. テストフレームワークpy.test 2.9.1

おかげ

答えて

3

別のオプションは、次のような、動的マネージャクラスを生成することであろう。

2

あなたが見ることができるように、そのエラーがDjangoのために起こっています関連するオブジェクトを呼び出すたびに新しいManagerをインスタンス化します。そのインスタンス化は余分なパラメータを取得しません。

このように値を取得するのではなく、モデルの属性にしてからself.modelを使って参照することができます。

def manager_factory(custom_field): 

    class MyManager(models.Manager): 
     my_field = custom_field 

     def get_queryset(self): 
      # getting some value 
      kwargs = {self.my_field: 'some-value'} 
      return super(MyManager, self).get_queryset().filter(**kwargs) 

    return MyManager() 


class MyModel(models.Model): 
    objects = manager_factory('custom_field') 

あなたはモデルクラスからマネージャーを切り離すことができますこの方法:

class MyManager(models.Manager): 
    def get_queryset(self): 
     # getting some value 
     kwargs = { self.model.manager_field_name: some_value } 

class B: 
    manager_field_name = 'my_field_name' 
    objects = MyManager() 
関連する問題