最近我遇到了一个关于Django的问题,模型继承以及如何创建模型实例。 假设我有以下(基本)设置:
class InviteBaseManager(models.Manager):
def create(self):
new_code = # create some kind of unique code, not really relevant here.
return super().create(code=new_code)
class InviteBase(models.Model):
code = models.CharField(max_length=10, blank=False, null=False, unique=True)
creationDate = models.DateTimeField(default=timezone.now())
objects = InviteBaseManager()
class PartyInviteManager(models.Manager):
def create(self, name):
# method 1
newInvite = InviteBase.objects.create()
print(newInvite.code) # is definitly set, lets assume "ABCD"
# as expexted, the "InviteBase" table has one row with code "ABCD" and
# default creationDate
newPartyInvite = super().create(partyName=name, invite=newInvite)
print(newPartyInvite.invite.code) # is EMPTY, prints nothing
# In fact, when looking at the db, there is still only *one* row in the table "InviteBase",
# with an *empty* code field and a default creationDate field.
return newPartyInvite
#method 2
newPartyInvite = super().create(partyName=name)
# creates the InviteBase instance implicitly, again, newPartyInvite.invite.code is empty.
# fill newPartyInvite.invity.code manually.
return newPartyInvite
class PartyInvite(InviteBase):
#Isn't blank=False and null=False unnecessary? A child should probably not exist with no parent?
invite = models.OneToOneField(InviteBase, parent_link=True, on_delete=models.CASCADE, null=False, blank=False)
partyName = models.CharField(...)
objects = PartyInviteManager()
所以问题是:如何在我的PartyInviteManager
的create
方法中传递已经存在的基类实例?即使使用方法1,我传递的现有的实例似乎也会被覆盖。将使用默认值创建一个新的。有趣的是,这违反了code
不能为空或NULL
的限制。你知道吗
我觉得这种行为有点奇怪?有人能指出我遗漏了什么吗?你知道吗
澄清一下:我知道我通常应该在create
方法中使用**kwargs
,继承可能不是这里理想的用例,但我只是对这种行为非常好奇。
我知道这种模型继承甚至不会为子模型创建pk
(因为将OneToOneField
保存到父类实际上充当了pk
),但是为什么不可能将手动创建的实例作为父类传递呢?我不允许在我的用例中使用继承吗?你知道吗
我想我找到了正确的方法:
PartyInviteManager
现在也从InviteManager
继承。从子管理器调用super.create()
时,将调用基管理器,并附加code
字段,所有操作都按预期进行。 我还发现,如果PartyInviteManager
没有从InviteBaseManager
继承,那么InviteBaseManager
的create
方法在创建新的PartyInvite
时不会被调用。我觉得这很奇怪。你知道吗当然,更简单的方法是通过函数将代码创建为默认值,如下所示:
但是,如果根据子类的不同,代码需要额外的信息(比如受邀请的成员或其他什么),那么这种方法将不再有效。你知道吗
另一方面,有趣的是以下代码片段:
生成以下输出:
在
PartyInviteManager
的create
方法中,可以直接使用code=XXXX
为InviteBase
模型传递字符串,另一方面invite_code
不起作用。你知道吗相关问题 更多 >
编程相关推荐