2016-08-31 7 views
1

私はすべての私のモデルは、同様の方法で__str__方法オーバーライドしたい:Djangoのすべてのモデルで__str__メソッドの一般的な実装を書くには?

class ShowModel(models.Model): 
    name = models.CharField(max_length=255) 

    def __init__(self): 
     self.to_show = 'name' 

    def _show(self): 
     if hasattr(self,self.to_show): 
      return str(getattr(self, self.to_show)) 
     else: 
      return str(getattr(self, 'id')) 

    def __str__(self): 
     return self._show() 

class MyModel1(ShowModel): 
    another_param = models.CharField(max_length=255) 

class MyModel2(ShowModel): 
    another_param = models.CharField(max_length=255) 

それは台無し:私は、継承を試してみましたので、私はすべてのモデルで同じコードを繰り返す必要はありません

class MyModel1(models.Model): 
    name = models.CharField(max_length=255) 

    def __init__(self): 
     self.to_show = 'name' 

    def _show(self): 
     if hasattr(self,self.to_show): 
      return str(getattr(self, self.to_show)) 
     else: 
      return str(getattr(self, 'id')) 

    def __str__(self): 
     return self._show() 

class MyModel2AndSoOn(models.Model): 
    another_param = models.CharField(max_length=255) 
    # same implementation of `__str__` but with another_param 

idMyModel1およびMyModel2に置き換えて、idShowModelへのポインタで置き換えることによって計算される。継承を持たない私のモデルに__str__メソッドの共通実装を書く方法、またはShowModelクラスをDjangoモデルとして扱うのを防ぐ方法は?

UPD: alecxe示唆したように私はabstractモデルを使用しますが、エラーメッセージが表示されて終わった:私は私のモデルオブジェクトのnameフィールドに値を割り当てる場合はすべてが正常に動作しますUPD

in _show 
    return str(getattr(self, self.to_show)) 
File "/path/to/my/project/env3/lib/python3.5/site-packages/django/db/models/fields/__init__.py", line 188, in __str__ 
model = self.model 
AttributeError: 'CharField' object has no attribute 'model' 

。ソリューション全体:テストケースで

class ShowModel(object): 
    to_show = 'name' 

    def _show(self): 
      if hasattr(self,self.to_show): 
       return str(getattr(self, self.to_show)) 
      elif hasattr(self,'id'): 
       return str(getattr(self, 'id')) 
      else: 
       return str(self) 

    def __str__(self): 
     return self._show() 

    class Meta: 
     abstract = True 

class MyModel1(ShowModel): 
    name = models.CharField(max_length=255) 
    to_show = 'name' 

class MyModel2(ShowModel): 
    another_param = models.CharField(max_length=255) 
    to_show = 'another_param' 

ua = MyModel1() 
ua.name = 'hi' 
print(ua) 
#prints hi 

ub = MyModel2() 
ub.another_param = 'hi again' 
print(ub) 
#prints hi again 

答えて

1

あなたはabstract modelを作成する必要があります。

class ShowModel(models.Model): 
    name = models.CharField(max_length=255) 

    def __init__(self): 
     self.to_show = 'name' 

    def _show(self): 
     if hasattr(self, "to_show"): 
      return str(getattr(self, "to_show")) 
     else: 
      return str(getattr(self, 'id')) 

    def __str__(self): 
     return self._show() 

    class Meta: 
     abstract = True 

そして、@itzmeontvするためにあなたのフォローアップの質問と感謝のためとして、 hasattr()getattr()を呼び出すときはself.to_showを "to_show"に置き換える必要があります。

+0

これは予想外に簡単な答えでした。しかし、それは次のエラーを出しました:Upd質問。 –

+0

私のクラスには属性 'show'がありません。 'to_show'を実行すると' hasattr(self、 'to_show') 'は' MyModel1'または 'ShowModel'に' to_show'属性があるかどうかをチェックしますが、 'MyModel'か' ShowModel'の値が ' to_show'すなわち 'name'属性 –

+0

しかし、とにかくソリューションに感謝します! –

関連する問題