我想记录用户所做的操作。在大多数 OO 语言中,我会通过一个 LoggedAction
类来实现它,它有几个子类,如 LoginAction
和 LogoutAction
。然后我可以遍历 LoggedAction
列表并通过虚拟继承获取特定的子行为。但是,这不适用于 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 登录”
。
正如预期的那样,这不起作用,因为我从 all()
得到的是 LoggedAction
对象的列表,这些对象具有 loginaction
成员或 logoutaction
成员。 (输出是一个消息列表,如 u'2012-02-18 18:47:09.105840: knatten
,没有提及操作。)
是否有一种理智的方式来获得我所追求的行为,或者我是否试图在这里应用错误的范例? (我想我是,而且我应该作为 LoggedAction
中的成员执行特定操作)
最佳答案
是的,这可能是错误的范式。很容易被对象关系映射器 (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()
魔术方法来获取完整描述。
关于python - 有没有一种在 Django 模型中模拟虚拟继承的明智方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9344252/