Django動態(tài)模型字段

這幾天準備寫個工作流系統(tǒng),因為工作流中一些模板的字段都是不固定的,于是思考有沒有動態(tài)的模型字段,剛好找到了某個大神寫的東西,覺得有用(還沒有實踐),于是記錄一下。

原文地址: https://stackoverflow.com/questions/7933596/django-dynamic-model-fields
翻譯地址:http://stackoverflow.org.cn/front/ask/view?ask_id=17340
我正在開發(fā)一個多租戶應用程序,其中一些用戶可以通過管理員定義自己的數(shù)據(jù)字段,以收集表單中的其他數(shù)據(jù)并報告數(shù)據(jù)。 后一位使JSONField不是一個很好的選擇,所以我有以下解決方案:

class CustomDataField(models.Model):
    """
    Abstract specification for arbitrary data fields.
    Not used for holding data itself, but metadata about the fields.
    """
    site = models.ForeignKey(Site, default=settings.SITE_ID)
    name = models.CharField(max_length=64)

    class Meta:
        abstract = True

class CustomDataValue(models.Model):
    """
    Abstract specification for arbitrary data.
    """
    value = models.CharField(max_length=1024)

    class Meta:
        abstract = True

注意CustomDataField如何具有一個ForeignKey到站點 - 每個站點將有一組不同的自定義數(shù)據(jù)字段,但使用相同的數(shù)據(jù)庫。 然后可以將各具體數(shù)據(jù)字段定義為:

class UserCustomDataField(CustomDataField):
    pass

class UserCustomDataValue(CustomDataValue):
    custom_field = models.ForeignKey(UserCustomDataField)
    user = models.ForeignKey(User, related_name='custom_data')

    class Meta:
        unique_together=(('user','custom_field'),)

這有以下用途

tom_field = UserCustomDataField.objects.create(name='zodiac', site=my_site) #probably created in the admin
user = User.objects.create(username='foo')
user_sign = UserCustomDataValue(custom_field=custom_field, user=user, data='Libra')
user.custom_data.add(user_sign) #actually, what does this even do?

但這感覺很笨重,特別是需要手動創(chuàng)建相關數(shù)據(jù)并將其與具體模型相關聯(lián)。 有更好的方法嗎?

已被搶先棄用的選項:

  • 自定義SQL即時修改表。 部分原因是因為這不會擴大,部分是因為它太多了。
  • 無數(shù)據(jù)解決方案,如NoSQL。 我沒有反對他們,但他們還不是很好。 最終這些數(shù)據(jù)是打字的,并且存在使用第三方報告應用程序的可能性。
  • JSONField,如上所列,因為它不會很好地與查詢。

原文有四個采納答案,但我覺得只有一種更合適,下面只記錄那一張答案。

JSONField:

JSON / JSONB字段支持任何JSON的可編碼的數(shù)據(jù)類型,而不僅僅是鍵/值對,但也往往是更快(對于JSONB)比Hstore更緊湊。幾個包實現(xiàn)JSON / JSONB字段,包括django-pgfields,但從Django 1.9,JSONField是一個內(nèi)置的使用JSONB存儲。
JSONField類似于HStoreField,并且可以使用大型字典執(zhí)行得更好。它還支持除字符串以外的類型,例如整數(shù),布爾和嵌套字典。

使用:

#app/models.py
from django.contrib.postgres.fields import JSONField
class Something(models.Model):
    name = models.CharField(max_length=32)
    data = JSONField(db_index=True)

在shell中創(chuàng)建:

>>> instance = Something.objects.create(
                 name='something',
                 data={'a': 1, 'b': 2, 'nested': {'c':3}}
           )

索引查詢幾乎與HStoreField相同,除了嵌套是可能的。 復雜索引可能需要手動創(chuàng)建(或腳本遷移)。

>> Something.objects.filter(data__a=1)
>>> Something.objects.filter(data__nested__c=3)
>>> Something.objects.filter(data__has_key='a')

感覺這個方法簡單,可以試一下

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容