Pra*_*aur 3 python django django-models
我正在Player
使用我的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)
Run Code Online (Sandbox Code Playgroud)
根据我的要求,我需要创建一个具有模型BookmarkPlayer
所有领域的新Player
模型.
现在我有两件事要做到这一点.
class BookmarkPlayer(Player): """ just a bookmark player""" class Meta: app_label = "core"
class BookmarkPlayer(models.Model): """ bookmark 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)
我只是想知道哪种方式做得更好.如果有另一种好办法,请与我分享.
更新的问题
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'
在这些更改后,当我运行我的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'
答:
最后,如果我们将ForeignKey或ManyToManyField上的related_name属性用于Abstract模型,我会得到答案.
这通常会导致抽象基类出现问题,因为此类中的字段包含在每个子类中,每次都具有完全相同的属性值(包括related_name).
要解决此问题,当您在抽象基类(仅)中使用related_name时,名称的一部分应包含'%(app_label)s'和'%(class)s'.
https://docs.djangoproject.com/en/dev/topics/db/models/#abstract-base-classes
现在我的BasePlayer模型是
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
如果您BookmarkPlayer
需要相同的数据但在不同的表中,抽象基础模型是最佳方式:
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
Run Code Online (Sandbox Code Playgroud)
这样,从模型中继承Player
并BookmarkPlayer
继承它们的字段BasePlayer
,但由于它BasePlayer
是抽象的,因此模型完全解耦.
另一方面,多表继承仍然会将字段保存在单个表中,但为表BookmarkPlayer
隐式添加一个额外OneToOneField
的Player
表.
归档时间: |
|
查看次数: |
901 次 |
最近记录: |