Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/355.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/7/css/40.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_Inheritance_Subclass - Fatal编程技术网

Python Django多表继承,如何知道哪个是模型的子类?

Python Django多表继承,如何知道哪个是模型的子类?,python,django,inheritance,subclass,Python,Django,Inheritance,Subclass,django中的多表继承有问题 让我们以银行账户为例 class account(models.Model): name = models…… class accounttypeA(account): balance = models.float….. def addToBalance(self, value): self.balance += value class accounttypeB(account): balance = mode

django中的多表继承有问题

让我们以银行账户为例

class account(models.Model):
    name = models……

class accounttypeA(account):
    balance = models.float…..

    def addToBalance(self, value):
        self.balance += value

class accounttypeB(account):
    balance = models.int…. # NOTE this

    def addToBalance(self, value):
        value = do_some_thing_with_value(value) # NOTE this
        self.balance += value
现在,我想给accounttype添加一个值,但我只有一个account对象,例如acc=account.object.get(pk=29)。那么,谁是acc的孩子

Django在accounttypeA和accounttypeB中自动创建一个account_ptr_id字段。因此,我的解决方案是:

child_class_list = ['accounttypeA', 'accounttypeB']

for cl in child_class_list:
    try:
        exec(“child = ” + str(cl) + “.objects.select_for_update().get(account_ptr_id=” +              str(acc.id) + “)”)
        logger.debug(“Child found and ready to use.”)
        return child
    except ObjectDoesNotExist:
        logger.debug(“Object does not exist, moving on…”)
也许这是一个绘图板的问题!:)


我希望我的例子已经很清楚了。谢谢

据我所知,没有Django内置的方法可以做到这一点

但是,给定acc=account.object.get(pk=29),您可以使用:

try:
    typeA = acc.accounttypeA
    # acc is typeA
except accounttypeA.DoesNotExist:
    # acc should be typeB if account only has typeA and typeB subclasses

try:
    typeB = acc.accounttypeB
    # acc is typeB
except accounttypeB.DoesNotExist:
    # acc should be typeA if account only has typeA and typeB subclasses

Django将两个字段添加到类
account
中:
accounttypea
accounttypeb
。如果您有pk=42的
accounttypeB
对象,您可以从父对象进行如下访问:

account.objects.get(pk=42).accounttypeb
>>> <accounttypeB instance>
但是您必须使用
accounttypeA.objects.create(…)
accounttypeB.objects.create(…)
创建模型,否则这个技巧将不起作用。 ()

我的解决方案基于

您可以使用
hasattr()
方法,如:

if hasattr(account, 'accounttypea'):
   account.accounttypea.<somefield> = <some value>
   do something here....

elif hasattr(account, 'accounttypeb'):
   account.accounttypeb.<somefield> = <some value>
   do something here...
if hasattr(账户'accounttypea'):
account.accounttypea.=
在这里做点什么。。。。
elif hasattr(账户“账户类型B”):
account.accounttypeb.=
在这里做点什么。。。

天气不太干燥,但很好用。:)

这正是我所做的;)你可以在上面看到。
class account(models.Model):
    name = models……

    def cast(self):
        """
        This method is quite handy, it converts "self" into its correct child class. For example:

        .. code-block:: python

           class Fruit(models.Model):
               name = models.CharField()

           class Apple(Fruit):
               pass

           fruit = Fruit.objects.get(name='Granny Smith')
           apple = fruit.cast()

        :return self: A casted child class of self
        """
        for name in dir(self):
            try:
                attr = getattr(self, name)
                if isinstance(attr, self.__class__) and type(attr) != type(self):                 
                    return attr
            except:
                pass

    @staticmethod
    def allPossibleAccountTypes():
        #this returns a list of all the subclasses of account (i.e. accounttypeA, accounttypeB etc)
        return [str(subClass).split('.')[-1][:-2] for subClass in account.__subclasses__()]

    def accountType(self):
        try:
            if type(self.cast()) == NoneType:
                #it is a child
                return self.__class__.__name__
            else:
                #it is a parent, i.e. an account
                return str(type(self.cast())).split('.')[-1][:-2]
        except:
            logger.exception()
    accountType.short_description = "Account type"

class accounttypeA(account):
    balance = models.float…..

    def addToBalance(self, value):
        self.balance += value

class accounttypeB(account):
    balance = models.int…. # NOTE this
if hasattr(account, 'accounttypea'):
   account.accounttypea.<somefield> = <some value>
   do something here....

elif hasattr(account, 'accounttypeb'):
   account.accounttypeb.<somefield> = <some value>
   do something here...