我想记录用户所做的操作。在大多数OO语言中,我会通过一个LoggedAction
类来实现它,它有几个子类,比如LoginAction
和LogoutAction
。然后我可以遍历LoggedAction
s的列表,并通过虚拟继承获得特定的子行为。但是,这在使用Django模型时不起作用。
示例:
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"
然后我想做
models.py
并得到一个类似[unicode(l) for l in LoggedAction.objects.all()]
的消息列表。正如所料,这不起作用,因为我从
u'2012-02-18 18:47:09.105840: knatten logged in'
得到的是一个all()
对象列表,其中要么有LoggedAction
成员,要么有loginaction
成员。(输出是一个消息列表,如logoutaction
,没有提到操作。)有没有一种理智的方法来获得我所追求的行为,或者我试图在这里应用错误的范式?(我想我是的,我应该作为
u'2012-02-18 18:47:09.105840: knatten
中的一个成员有具体的行动) 最佳答案
是的,这可能是错误的模式。很容易被对象关系映射器(ORM)误导——数据库表并没有很好地映射到对象,这种差异被称为object-relational impedance mismatch。
你真正需要的是把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())
注意,我使用了任意的单个字符串来表示操作,使用
get_action_display()
magic方法来获得完整的描述。