MongoEngine - функция вызова только при создании документа или установке определенного поля?

Я не уверен, что является лучшим / питоническим способом создания пользовательского документа, который автоматически хеширует свой пароль при создании.

Рассмотрим следующую модель mongoengine:

class User(Document):
    email = EmailField(required=True, primary_key=True)
    name = StringField(required=True)
    pswd = StringField(required=True)

    def check_pswd(self, password):
        return verify_password(password, self.pswd)

    def hash_pswd(self, password):
        return hash_password(password):

    def save(self, *args, **kwargs):
        self.pswd = self.hash_pswd(self.pswd)
        super().save(*args, **kwargs)

Когда я создаю пользователя, он отлично работает:

user = User()
user.email = '[email protected]'
user.pswd = 'password'
user.name = 'User'
user.save()

Но если я обновлю его, он удвоит хеш-пароль, я этого не хочу.

#User wants to change his name
user = User.objects(email='[email protected]')
user.name = 'User 2'
user.save()

Есть ли способ хешировать его пароль только при создании или изменении пароля?

Или, может быть, мне следует делегировать ответственность за хеширование пароля представлению / контроллеру?


person Mojimi    schedule 12.07.2019    source источник


Ответы (1)


Я не даю вам образец кода, вы можете использовать метод Document.update (), который обновит только те поля, которые были изменены.

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

  1. Проверьте, изменил ли пользователь пароль (сравнив существующий сохраненный хэш и новый хеш, если он есть)
  2. Если новый хеш отличается, значит, пользователь изменил пароль, в этом случае вы можете нажать метод Document.update.
  3. Если нет, не вызывайте обновление в этом поле.

В качестве альтернативы update в Mongoengine принимает итерацию, поэтому вы можете просто создать список или объект словаря и убедительно выбрать Удалить из него хэш-поле пароля.

Что касается того, кто должен выполнять это, то есть View / Controller, это решение дизайна, но я бы предпочел отделить представление (GUI / Front End) от логики, поэтому я бы делегировал это контроллеру или даже более внутренне объекту, который отвечает за обрабатывая все задачи, связанные с базой данных / сетью, таким образом он будет изолирован и легко модифицирован. И не усложняет или не замедляет процесс / поток объектов просмотра

Ссылка для обновления с использованием итеративного типа Dict. вопрос о stackoverflow для обновления Mongoengine с итеративным

Ссылка, в которой обсуждаются устаревшие методы сохранения (Сопровождающий прокомментировал ниже, что метод сохранения не является устаревшим, поэтому доверяйте ему / ей и продолжайте по этой ссылке) Метод сохранения Mongoengine устарел?

Ссылка на метод обновления в mongoengine. Mongoengine Atomic Update

person german_wings    schedule 12.07.2019
comment
Я понятия не имел, что сохранение устарело, все учебники в документации используют сохранение. - person Mojimi; 12.07.2019
comment
Я придерживаюсь официального драйвера mongodb для python, чтобы избежать таких сюрпризов ????, проверяли ли вы метод обновления в mongoengine или повторяемый, я думаю, это может быть полезно в вашем случае, я могу поставить образец кода, когда вернусь домой. Хорошего дня - person german_wings; 12.07.2019
comment
Нет, нормально, я понял, как это сделать. - person Mojimi; 12.07.2019
comment
На самом деле, читая mongoengine, я не думаю, что они намерены отказаться от сохранения: mongoengine.readthedocs.io/en/latest/, возможно, внутри он вызывает pymongo insert_one - person Mojimi; 12.07.2019
comment
Сопровождающий Mongoengine, "save" вообще не устарел !! - person bagerard; 13.07.2019
comment
Я просто изменил вышеупомянутый пост, чтобы избежать путаницы, я предлагаю вам неожиданно появиться по ссылке, о которой я упоминал выше, чтобы очистить воздух ???? и там. - person german_wings; 13.07.2019