我正在使用我的django應用程序模型Player
。創建一個新模型,其中包含當前現有模型的所有字段
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類。
class BookmarkPlayer(Player): """ just a bookmark player""" class Meta: app_label = "core"
- 我可以定義成BookmarkPlayer模型播放器模型的所有字段。
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屬性爲抽象模型。
這通常會導致抽象基類中的問題,因爲此類中的字段包含在每個子類中,每次屬性(包括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
還有其他幾種更好的方法可以做到這一點,但這取決於您的確切要求,哪一個最好。首先你想要兩個模型的原因是什麼? – knbk 2014-12-03 12:54:25
我想爲播放器的詳細信息添加書籤,以便我可以在我的網站上分享用戶之間的會話。 – 2014-12-03 13:11:53
因此,如果我理解正確,您基本上想要在特定時刻複製'Player'的詳細信息並將其另存爲BookmarkPlayer?在那種情況下,看到我的答案,那將是最好的方法。添加一些便利方法來將'Player'轉換爲'BookmarkPlayer'也很容易,反之亦然。 – knbk 2014-12-03 13:16:33