[英]Dynamically set class attributes (model fields) while iterating a dictionary
我正在嘗試根據字典中包含的鍵,值對動態定義模型的字段。
我嘗試了兩種方法:
字典是:
NOTIFICATION_TYPES = {
'friend_request_received': 0,
'friend_request_accepted': 1,
# eccetera
}
非常錯誤(因為未定義self而生成異常):
class EmailNotification(models.Model):
"""
User Email Notification Model
Takes care of tracking the user's email notification preferences
"""
user = models.OneToOneField(User, verbose_name=_('user'))
for key, value in NOTIFICATION_TYPES.items():
setattr(self, key, models.BooleanField(_('notify new matches'), default=True))
class Meta:
db_table = 'profile_email_notification'
顯然錯誤但不創建模型字段:
class EmailNotification(models.Model):
"""
User Email Notification Model
Takes care of tracking the user's email notification preferences
"""
user = models.OneToOneField(User, verbose_name=_('user'))
def __init__(self, *args, **kwargs):
for key, value in NOTIFICATION_TYPES.items():
setattr(self.__class__, key, models.BooleanField(_(key), default=True))
super(EmailNotification, self).__init__(*args, **kwargs)
class Meta:
db_table = 'profile_email_notification'
有可能做我想做的事嗎? 我確定是的!
在定義類之后,您需要設置這些額外的屬性:
class EmailNotification(models.Model):
"""
User Email Notification Model
Takes care of tracking the user's email notification preferences
"""
user = models.OneToOneField(User, verbose_name=_('user'))
class Meta:
db_table = 'profile_email_notification'
for key, value in NOTIFICATION_TYPES.items():
setattr(EmailNotification, key, models.BooleanField(_('notify new matches'), default=True))
您可以使用類裝飾器將for循環包裝到應用於該類的函數中:
def add_notification(cls):
for key, value in NOTIFICATION_TYPES.items():
setattr(cls, key, models.BooleanField(_('notify new matches'), default=True))
return cls
@add_notification
class EmailNotification:
# ...
我有點擔心Django元類處理要處理這些字段,您可能需要添加其他調用以使EmailNotification._meta
結構知道您添加的其他字段。
你可以使用類裝飾器:
def add_notification(cls):
for key in NOTIFICATION_TYPES:
setattr(cls, key, models.BooleanField(_('notify new matches'), default=True))
return cls
@add_notification
class EmailNotification(models.Model):
"""
User Email Notification Model
Takes care of tracking the user's email notification preferences
"""
user = models.OneToOneField(User, verbose_name=_('user'))
class Meta:
db_table = 'profile_email_notification'
感謝答案中的建議,但有一個關鍵缺失的概念。
必須做兩件事:
setattr(myclass, key, field)
myclass.add_to_class(key, field)
一個有效的解決方案:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.