3

ユーザーが行ったアクションをログに記録したい。ほとんどの OO 言語では、や などLoggedActionのいくつかの子クラスを持つクラスを介してこれを実装します。その後、 のリストを反復処理し、 仮想継承を通じて特定の子の動作を取得できます。ただし、これは Django モデルでは機能しません。LoginActionLogoutActionLoggedAction

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()のリストだからです。(出力は のようなメッセージのリストであり、アクションについては言及されていません。)LoggedActionloginactionlogoutactionu'2012-02-18 18:47:09.105840: knatten

私が求めている動作を取得するための適切な方法はありますか、またはここで間違ったパラダイムを適用しようとしていますか? (私はそうだと思います. のメンバーとして特定のアクションを実行する必要がありますLoggedAction)

4

2 に答える 2

2

はい、これはおそらく間違ったパラダイムです。オブジェクト リレーショナル マッパー (ORM) に惑わされがちです。データベース テーブルは実際にはオブジェクトにうまくマッピングされません。この違いは、オブジェクト リレーショナル インピーダンスの不一致として知られています。

実際に必要なのはaction、フィールドを作成することです。このフィールドは、そのフィールドの可能な値を表すパラメーターを取ることができchoicesます。つまり、ログインまたはログアウトします。

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())

アクションを表すために任意の 1 文字の文字列を使用しget_action_display()、完全な説明を取得するためにマジック メソッドを使用したことに注意してください。

于 2012-02-18T22:46:14.813 に答える
1

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

于 2012-02-18T22:05:19.860 に答える