0

辞書に含まれているキーと値のペアに応じて、モデルのフィールドを動的に定義しようとしています。

私は2つの方法を試みました:

辞書は次のとおりです。

NOTIFICATION_TYPES = {
    'friend_request_received': 0,
    'friend_request_accepted': 1,
    # eccetera
}

非常に間違っています(自己が定義されていないため、例外が生成されます):

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'

私がやろうとしていることをすることは可能ですか?きっとそうです!

4

3 に答える 3

1

クラスデコレータを使用できます。

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'
于 2013-03-17T13:24:50.723 に答える
1

クラスを定義した、これらの追加の属性を設定する必要があります。

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ます。追加したフィールドを構造体に認識させるために、追加の呼び出しを追加する必要がある場合があります。

于 2013-03-17T13:22:59.180 に答える
0

回答の提案のおかげで、重要な概念が欠けていました。

次の 2 つのことを行う必要があります。

setattr(myclass, key, field)
myclass.add_to_class(key, field)

ここでの実用的なソリューション:

https://github.com/nemesisdesign/nodeshot/blob/7798f81d558791499039afab1c860483fe30dd77/nodeshot/community/notifications/models/user_settings.py#L6

于 2013-08-22T09:03:08.473 に答える