2012-02-18 4 views
3

ユーザーが行った操作をログに記録します。ほとんどのオブジェクト指向言語では、とLogoutActionのようないくつかの子クラスを持つLoggedActionクラスを使って実装します。その後、LoggedActionのリストを反復し、仮想継承を使って特定の子の動作を取得することができました。しかしこれはDjangoモデルを使っては動作しません。Djangoモデルで仮想継承をシミュレートするための良い方法はありますか?

models.py

class LoggedAction(models.Model): 
    user = models.ForeignKey(User) 
    timestamp = models.DateTimeField(auto_now_add=True) 

    def __unicode__(self): 
     return "%s: %s %s" % (unicode(self.timestamp), unicode(self.user), unicode(self.action())) 

    def action(self): 
     return "" 

class LoginAction(LoggedAction): 
    def action(self): 
     return "logged in" 

class LogoutAction(LoggedAction): 
    def action(self): 
     return "logged out" 

それから私は[unicode(l) for l in LoggedAction.objects.all()]を行うとu'2012-02-18 18:47:09.105840: knatten logged in'のようなメッセージのリストを取得したいのですが。私がall()から取得するloginactionメンバーまたはlogoutactionメンバーのいずれかを有するLoggedActionオブジェクトのリストがあるので、

予想したように、これは、動作しません。 (出力は、アクションのは言及しないで、u'2012-02-18 18:47:09.105840: knattenのようなメッセージのリストです。)

は、私は後だ、または私はここで間違ったパラダイムを適用しようとしている動作を取得するためにまとも方法はありますか? (私は、私はちょうど、LoggedActionのメンバーとして特別な行動を取るべきだと思います)

+0

ここに示したように、データベースでは3つのテーブルとして実装され、LoginActionとLogoutActionは共通のテーブルに結合され、LoggedActionオブジェクトはインスタンス化できます。 LoggedActionを抽象化することができます。 –

+0

@ChrisMorgan 'LoggedAction'抽象クラスを抽象化すると、それらを反復処理することはできません。したがって特に 'LoggedAction.objects.all()'は不可能でしょうか? – knatten

+0

わかりません。実際、私はサブクラスを使ってモデルを繰り返し処理する必要はありませんでした。 –

答えて

2

はい、これはおそらく間違ったパラダイムです。オブジェクト・リレーショナル・マッパー(ORM)に誤解を与えるのは簡単です。データベース表は実際にすべてのオブジェクトをオブジェクトにマップするわけではありません。この違いはobject-relational impedance mismatchとして知られています。

実際に必要なのは、actionをフィールドにすることです。私はアクションを表現するために、任意の単一文字列を使用しました

class LoggedAction(models.Model): 
    ACTIONS = (
     ('I', 'logged in'), 
     ('O', 'logged out') 
    ) 
    user = models.ForeignKey(User) 
    timestamp = models.DateTimeField(auto_now_add=True) 
    action = models.CharField(max_length=1, choices=ACTIONS) 

    def __unicode__(self): 
     return u"%s: %s %s" % (self.timestamp, self.user, self.get_action_display()) 

注意、およびget_action_display()マジック:すなわち、ログインまたはログアウト - このフィールドには、そのフィールドの可能な値を表しchoicesパラメータを取ることができますメソッドを使用して完全な説明を取得します。

+0

ええ、おそらく、リレーショナルデータベースの上に完全なOOを叩くことができると期待するのはちょっと楽観的です。 サブクラスにいくつかの余分な情報を保存したいと思っていますが、おそらくすべてが 'TextField'でしょう。だから、私はあなたの解決策に行くことができると思う、 'LoggedAction'クラスの' TextField'を持っています。 – knatten

1

django-model-utilsからInheritanceManagerを見てください。具体的なサブクラスを取得することができます。

関連する問題