Python Django多表继承,如何知道哪个是模型的子类?
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
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...