Какое правило / руководство нарушает этот принцип (добавление атрибутов в экземпляр orm) - PullRequest
0 голосов
/ 25 января 2019

я наткнулся на этот код:

class MyModel(model.Model):
    def __init__(self, *args, **kwargs):
        self._log_data = dict()
        super(MyModel, self).__init__(*args, **kwargs)

    def send_data(self, obj):
        self._log_data['foo'] = obj.foo
        ...

У меня просто такое ощущение, что добавление ._log_data к экземпляру orm неверно.

До сих пор у меня было такое ощущение, что эта реализация неочевидна, и мне не хватает соответствующего термина.

Согласно какому правилу / руководству это не чистый / хороший код?

1 Ответ

0 голосов
/ 25 января 2019

Если вы не возражаете, я рекомендую установить _log_data в качестве переменной класса.

class MyModel(models.Model):
    _log_data = None
    field_a = models.IntegerField(null=True)

    def send_data(self, bar):
        if self._log_data is None:
            self._log_data = dict()
        self._log_data['foo'] = bar

Тест в оболочке django:

a = MyModel()
print(a._log_data)
>>> None
a.send_data('asdf')
print(a._log_data)
>>> {'foo': 'asdf'}
print(MyModel._log_data)
>>> None
b = MyModel()
print(b._log_data)
>>> None

Можно подтвердить, что переменная класса делаетне влияет на другие объекты вообще.И это используется в AbstractBaseUser модели django.

class AbstractBaseUser(models.Model):
    password = models.CharField(_('password'), max_length=128)
    last_login = models.DateTimeField(_('last login'), blank=True, null=True)

    is_active = True

    REQUIRED_FIELDS = []

    # Stores the raw password if set_password() is called so that it can
    # be passed to password_changed() after the model is saved.
    _password = None

    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)
        if self._password is not None:
            password_validation.password_changed(self._password, self)
            self._password = None

    def set_password(self, raw_password):
        self.password = make_password(raw_password)
        self._password = raw_password

Так что я не думаю, что это нарушает правила.

+ ps: Я хочу, чтобы вы указали, если яне в точку.

...