Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在Django模型中有没有一种合理的方法来模拟虚拟继承?_Python_Django_Oop_Inheritance_Virtual Inheritance - Fatal编程技术网

Python 在Django模型中有没有一种合理的方法来模拟虚拟继承?

Python 在Django模型中有没有一种合理的方法来模拟虚拟继承?,python,django,oop,inheritance,virtual-inheritance,Python,Django,Oop,Inheritance,Virtual Inheritance,我想记录用户所做的操作。在大多数OO语言中,我会通过一个LoggedAction类来实现这一点,它有几个子类,如LoginAction和LogoutAction。然后,我可以遍历LoggedActions列表,并通过虚拟继承获得特定的子行为。但是,使用Django模型时,这不起作用 示例models.py: class LoggedAction(models.Model): user = models.ForeignKey(User) timestamp = models.Dat

我想记录用户所做的操作。在大多数OO语言中,我会通过一个
LoggedAction
类来实现这一点,它有几个子类,如
LoginAction
LogoutAction
。然后,我可以遍历
LoggedAction
s列表,并通过虚拟继承获得特定的子行为。但是,使用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"
然后我想在LoggedAction.objects.all()中对l执行
[unicode(l)for l
,并获得一个消息列表,如
u'2012-02-18 18:47:09.105840:knatten logged in'

正如预期的那样,这不起作用,因为我从
all()
中得到的是一个
LoggedAction
对象列表,其中包含
loginaction
成员或
logoutaction
成员。(输出是一个消息列表,如
u'2012-02-18 18:47:09.105840:knatten
,没有提及操作。)


有没有一种理智的方法来获得我所追求的行为,或者我试图在这里应用错误的范式?(我想是的,我应该在
LoggedAction
中作为一名成员执行特定操作)

看看django model UTIL。它允许您获得具体的子类。

是的,这可能是错误的范例。很容易被对象关系映射器(ORM)误导——数据库表并没有很好地映射到对象,这种差异被称为

您实际需要的是将
操作
设置为一个字段。此字段可以采用表示该字段可能值的
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\u action\u display()
magic方法来获得完整的描述。

请注意,正如您在这里所示,它将在数据库中作为三个表实现,LoginAction和LogoAction连接在一个公共表上,并且可以实例化LoggedAction对象。您可能想将LoggedAction抽象化。@ChrisMorgan如果我将
LoggedAction
抽象化,我将无法对它们进行迭代,对吗?所以特别是
LoggedAction.objects.all()
将是不可能的?不确定;事实上,我从来没有理由用子类迭代一个模型。是的,期望能够在关系数据库上实现完整的OO可能有点乐观。我希望能够在子类中存储一些额外的信息,但它们可能都是
TextField
。因此,我想我可以使用您的解决方案,在
LoggedAction
类中设置
TextField