Python 创建一个新模型,其中包含当前现有模型的所有字段
Python 创建一个新模型,其中包含当前现有模型的所有字段,python,django,django-models,Python,Django,Django Models,我的django应用程序有一个型号播放器
class Player(models.Model):
""" player model """
name = models.CharField(max_length=100, null=True, blank=True)
date_created = models.DateTimeField(auto_now_add=True)
last_updated = models.DateTimeField(auto_now=T
我的django应用程序有一个型号播放器
class Player(models.Model):
""" player model """
name = models.CharField(max_length=100, null=True, blank=True)
date_created = models.DateTimeField(auto_now_add=True)
last_updated = models.DateTimeField(auto_now=True)
hash = models.CharField(max_length=128, null=True, blank=True)
bookmark_url = models.CharField(max_length=300, null=True, blank=True)
根据我的要求,我需要创建一个新的模型BookmarkPlayer
,其中包含Player
模型的所有字段
现在我有两件事要做
我可以为BookmarkPlayer模型扩展Player类
类书签播放器(播放器):
“只是一个书签播放器”
类元:
app_label=“核心”
我可以将播放器模型的所有字段定义为书签播放器模型
类书签播放器(models.Model):
“”“书签播放器型号”“”
name=models.CharField(最大长度=100,null=True,blank=True)
date\u created=models.DateTimeField(auto\u now\u add=True)
last_updated=models.DateTimeField(自动_now=True)
hash=models.CharField(最大长度=128,null=True,blank=True)
bookmark\u url=models.CharField(最大长度=300,null=True,blank=True)
我只是想知道哪种方法更好。如果有其他好方法,请与我的朋友分享
更新的问题
Knbb创建基类的想法很有趣,但我面临的问题是我的一个模型已经存在于数据库中
我的实际型号:
class Address(models.Model):
address = models.TextField(null=True, blank=True)
class Site(models.Model):
domain = models.CharField(max_length=200)
class Player(models.Model):
# ... other fields
shipping_address = models.ForeignKey(Address, related_name='shipping')
billing_address = models.ForeignKey(Address, related_name='billing')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now_add=True)
site = models.ManyToManyField(Site, null=True, blank=True)
class Meta:
abstract = True
class Address(models.Model):
address = models.TextField(null=True, blank=True)
class Site(models.Model):
domain = models.CharField(max_length=200)
class BasePlayer(models.Model):
# .. other fields
shipping_address = models.ForeignKey(Address, related_name='shipping')
billing_address = models.ForeignKey(Address, related_name='billing')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now_add=True)
site = models.ManyToManyField(Site, null=True, blank=True)
class Meta:
abstract = True
class Player(BasePlayer):
class Meta:
app_label = 'core'
class BookmarkPlayer(BasePlayer):
class Meta:
app_label = 'core'
类地址(models.Model):
address=models.TextField(null=True,blank=True)
班级站点(models.Model):
domain=models.CharField(最大长度=200)
类播放器(models.Model):
# ... 其他领域
shipping\u address=models.ForeignKey(地址,相关的\u name='shipping')
计费地址=型号。外键(地址,相关的\u name='billing')
已创建\u at=models.DateTimeField(自动\u now\u add=True)
更新的\u at=models.DateTimeField(自动\u now\u add=True)
site=models.ManyToManyField(site,null=True,blank=True)
类元:
抽象=真
更改后的型号:
class Address(models.Model):
address = models.TextField(null=True, blank=True)
class Site(models.Model):
domain = models.CharField(max_length=200)
class Player(models.Model):
# ... other fields
shipping_address = models.ForeignKey(Address, related_name='shipping')
billing_address = models.ForeignKey(Address, related_name='billing')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now_add=True)
site = models.ManyToManyField(Site, null=True, blank=True)
class Meta:
abstract = True
class Address(models.Model):
address = models.TextField(null=True, blank=True)
class Site(models.Model):
domain = models.CharField(max_length=200)
class BasePlayer(models.Model):
# .. other fields
shipping_address = models.ForeignKey(Address, related_name='shipping')
billing_address = models.ForeignKey(Address, related_name='billing')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now_add=True)
site = models.ManyToManyField(Site, null=True, blank=True)
class Meta:
abstract = True
class Player(BasePlayer):
class Meta:
app_label = 'core'
class BookmarkPlayer(BasePlayer):
class Meta:
app_label = 'core'
类地址(models.Model):
address=models.TextField(null=True,blank=True)
班级站点(models.Model):
domain=models.CharField(最大长度=200)
BasePlayer类(models.Model):
# .. 其他领域
shipping\u address=models.ForeignKey(地址,相关的\u name='shipping')
计费地址=型号。外键(地址,相关的\u name='billing')
已创建\u at=models.DateTimeField(自动\u now\u add=True)
更新的\u at=models.DateTimeField(自动\u now\u add=True)
site=models.ManyToManyField(site,null=True,blank=True)
类元:
抽象=真
职业球员(棒球运动员):
类元:
应用程序标签='核心'
类书签播放器(BasePlayer):
类元:
应用程序标签='核心'
在这些更改之后,当我运行django服务器时,我会收到下面给出的错误
django.core.management.base.CommandError: One or more models did not validate:
core.test1: Accessor for field 'shipping_address' clashes with related field 'Address.shipping'. Add a related_name argument to the definition for 'shipping_address'.
core.test1: Reverse query name for field 'shipping_address' clashes with related field 'Address.shipping'. Add a related_name argument to the definition for 'shipping_address'.
core.test1: Accessor for field 'billing_address' clashes with related field 'Address.billing'. Add a related_name argument to the definition for 'billing_address'.
core.test1: Reverse query name for field 'billing_address' clashes with related field 'Address.billing'. Add a related_name argument to the definition for 'billing_address'.
core.test2: Accessor for field 'shipping_address' clashes with related field 'Address.shipping'. Add a related_name argument to the definition for 'shipping_address'.
core.test2: Reverse query name for field 'shipping_address' clashes with related field 'Address.shipping'. Add a related_name argument to the definition for 'shipping_address'.
core.test2: Accessor for field 'billing_address' clashes with related field 'Address.billing'. Add a related_name argument to the definition for 'billing_address'.
core.test2: Reverse query name for field 'billing_address' clashes with related field 'Address.billing'. Add a related_name argument to the definition for 'billing_address'
django.core.management.base.CommandError:一个或多个模型未验证:
core.test1:字段“shipping\u address”的访问器与相关字段“address.shipping”冲突。在“配送地址”的定义中添加相关的\u name参数。
core.test1:字段“shipping\u address”的反向查询名称与相关字段“address.shipping”冲突。在“配送地址”的定义中添加相关的\u name参数。
core.test1:字段“billing_address”的访问器与相关字段“address.billing”冲突。在“账单地址”的定义中添加相关的\u name参数。
core.test1:字段“billing_address”的反向查询名称与相关字段“address.billing”冲突。在“账单地址”的定义中添加相关的\u name参数。
core.test2:字段“shipping_address”的访问器与相关字段“address.shipping”冲突。在“配送地址”的定义中添加相关的\u name参数。
core.test2:字段“shipping_address”的反向查询名称与相关字段“address.shipping”冲突。在“配送地址”的定义中添加相关的\u name参数。
core.test2:字段“billing_address”的访问器与相关字段“address.billing”冲突。在“账单地址”的定义中添加相关的\u name参数。
core.test2:字段“billing_address”的反向查询名称与相关字段“address.billing”冲突。在“账单地址”的定义中添加相关的\u name参数
回答:
最后,我得到了一个答案,如果我们将ForeignKey或ManyToManyField上的related_name属性用于抽象模型中。
这通常会导致抽象基类出现问题,因为此类上的字段包含在每个子类中,每次属性值(包括相关名称)都完全相同。
要解决此问题,当您在抽象基类(仅)中使用相关名称时,名称的一部分应包含“%”(应用程序标签)s”和“%”(类)s”。
现在我的棒球运动员模型是
class BasePlayer(models.Model):
# .. other fields
shipping_address = models.ForeignKey(Address, related_name='%(app_label)s_%(class)s_shipping')
billing_address = models.ForeignKey(Address, related_name='%(app_label)s_%(class)s_billing')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now_add=True)
site = models.ManyToManyField(Site, null=True, blank=True)
class Meta:
abstract = True
BasePlayer类(models.Model):
# .. 其他领域
shipping_address=models.ForeignKey(地址,相关_名称='%(应用程序标签)s_u%(类)s_shipping')
计费地址=型号。外键(地址,相关的\u名称='%(应用程序\u标签)s\u%(类)s\u计费')
已创建\u at=models.DateTimeField(自动\u now\u add=True)
更新的\u at=models.DateTimeField(自动\u now\u add=True)
site=models.ManyToManyField(site,null=True,blank=True)
类元:
抽象=真
这里有一些关于模型继承的好信息:
选项2将引入复制,这总是不好的。如果BookmarkPlayer
没有任何新字段,只有不同的方法,我建议您使用链接中描述的“代理模型”选项,因为您不需要BookmarkPlayer
在数据库中拥有自己的表
如果它需要自己的表,“多表插入”是最好的方法,这将是您问题中的选项1如果您的书签播放器
需要相同的数据,但在不同的表中,则抽象基础模型是最好的方法:
class BasePlayer(models.Model):
name = models.CharField(max_length=100, null=True, blank=True)
date_created = models.DateTimeField(auto_now_add=True)
last_updated = models.DateTimeField(auto_now=True)
hash = models.CharField(max_length=128, null=True, blank=True)
bookmark_url = models.CharField(max_length=300, null=True, blank=True)
class Meta:
abstract = True
class Player(BasePlayer):
""" player model """
pass
class BookmarkPlayer(BasePlayer):
""" bookmark player model """
pass
这样一来,Player
和