2016-07-07 4 views
2

OneToOneFieldとリンクしているモデルがあります。例:現在のモデルに見つからない場合は、1対1のリンクされたモデルのすべての属性にアクセスします。

class Profile(models.Model): 
    #other fields ... 
    user = models.OneToOneField(User, null=True, blank=True) 

属性がプロファイルまたはユーザーに存在する場合は、ドット表記で属性を取得したいと考えています。例えば

class Profile(models.Model): 
    .... 

    def __getattr__(self, name): 
     if self.user: 
      return self.user.name 
     else: 
      raise AttributeError 
     return super().__getattr__(self,name) 

Profileemailフィールドを持っていない場合、私はそれがUserに存在する場合(profileProfileインスタンスである)profile.emailとしてそれを取得したいと思い:私は次のことをやりました。

ただし、以下のようなエラーが発生します。

if self.user: 
RuntimeError: maximum recursion depth exceeded 

どのように私は、この動作を達成することができます - 現在のインスタンスから属性を取得し、利用できない場合、および1対1のフィールドはどれも、そこに引きませんか?

+0

達成しようとしている動作がわかりません。なぜ 'Profile'モデルに' profile'属性がありますか?あなたは 'getattr(self.profile、name)を返す'を意味しますか? – miyamoto

+0

@miyamoto私は修正しました。私は実際に 'self.user'を意味しました。ありがとう。 – DurgaDatta

答えて

1

何かが好きですか?

def __getattr__(self, name): 
    if hasattr(self, name): 
     return getattr(self, name) 
    elif hasattr(self, "user") and hasattr(self.user, name): 
     return getattr(self.user, name) 
    else: 
     raise AttributeError 
+0

これも同じエラーになります。 – DurgaDatta

2

この方法は必要ありません。どのようなモデルにどのような属性があるのか​​を知っているので、なぜ盲目的にメソッドを呼び出すべきですか?これは他の共同開発者を混乱させるので、これを行うべきではありません。最悪の場合、私はプロパティを作成します:

@property 
def get_name(self): 
    if hasattr(self, 'name'): 
     return self.name 
    return self.user.first_name # there is no name field in django user model 
+0

私が与えた例はデモンストレーションのためのものです。私は標準モデルのためにそのアプローチを「使用」として使用しません。しかし、私はカスタムモデルを持っており、いくつかの属性(プロパティ、フィールド、メソッド)があり、それらのすべてにアクセスしたいと思います。 – DurgaDatta

+0

@Durga「すべての人」という意味です。あなたは常にそのすべてにアクセスできます。この質問につながる中核的な問題はどこですか? – doniyor

+0

それぞれのプロパティまたは個々のアクセスを記述したくありません。 – DurgaDatta

関連する問題