Python 在迭代字典时动态设置类属性(模型字段)

Python 在迭代字典时动态设置类属性(模型字段),python,django,django-models,python-2.7,Python,Django,Django Models,Python 2.7,我试图根据字典中包含的键、值对动态定义模型的字段 我尝试了两种方法: 字典是: NOTIFICATION_TYPES = { 'friend_request_received': 0, 'friend_request_accepted': 1, # eccetera } 错误(由于未定义self,因此生成异常): 显然错误较小,但不会创建模型字段: class EmailNotification(models.Model): """ User Email

我试图根据字典中包含的键、值对动态定义模型的字段

我尝试了两种方法:

字典是:

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'))

    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))
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:
    # ...
可以使用将for循环包装到应用于类的函数中:

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))
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元类处理想要处理这些字段,您可能需要添加额外的调用来发出
电子邮件通知。_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)
这里有一个可行的解决方案: