Проверка соответствия уникальности при проверке формы в App Engine

Я использую Flask и WTforms в App Engine, пытаясь реализовать ограничение уникальности в одном из полей. Вопрос большой, пожалуйста, будьте терпеливы, и я застрял здесь много часов, вам нужна помощь от вас. Начал обучение App Engine, Flask и WTForms месяц назад. Заранее спасибо.

Приложение имеет модель «Команда», как показано ниже:

  • Загрузка и процесс загрузки файлов в бутылки
  • class Team(db.Model): name = db.StringProperty(required=True) -- some other fields here -- 

    Требование: имя команды должно быть уникальным.

    Я следил за ссылками

    • http://www.codigomanso.com/en/2010/09/solved-anadir-claves-unicas-en-google-app-engine-en-3-lineas/
    • http://squeeville.com/2009/01/30/add-a-unique-constraint-to-google-app-engine/
    • http://csimms.botonomy.com/2012/07/there-are-only-two-ways-to-enforce-unique-constraints-in-google-app-engine.html

    Придумали следующий код:

    models.py: Создал отдельную таблицу «Уникальный», как указано в ссылке:

     class Unique(db.Model): """ Handles uniqueness constriant on a field """ @classmethod def unique_check(cls, form_name, field_data): def tx(form_name, field_data): key_name = "%s%s" % (form_name, field_data) uk = Unique.get_by_key_name(key_name) app.logger.debug("UK:" + str(uk)) if uk: return False uk = Unique(key_name=key_name) uk.put() return True ret_val = db.run_in_transaction(tx, form_name, field_data) app.logger.debug("ret_val:" + str(ret_val)) return ret_val 

    forms.py: Я переопределил функцию __init __ () и validate_on_submit (), в которой проверяется уникальность, и если она не уникальна, к этому полю присоединяется ошибка, и ошибка проверки будет поднята так же, как и валидаторы wtforms.

     class TeamForm(wtf.Form): def __init__(self, *args, **kwargs): super(TeamForm, self).__init__(*args, **kwargs) if kwargs.get('edit', None): self.old_name = self.name.data.lower() def validate_on_submit(self, edit=False): if not super(TeamForm, self).validate_on_submit(): return False if edit: if self.old_name and self.old_name != self.name.data.lower(): Unique.delete_entity(self.__class__.__name__, self.old_name) if not Unique.unique_check(self.__class__.__name__, self.name.data.lower()): self.name.errors.append("Value '%s' is not unique" % self.name.data) return False else: if not Unique.unique_check(self.__class__.__name__, self.name.data.lower()): self.name.errors.append("Value '%s' is not unique" % self.name.data) return False return True **---- Form fields declaration ----** 

    Вышеупомянутый код работает, когда новая команда вставлена. Я имею в виду, что он правильно проверяет уникальность. Проблема возникает, когда пользователь редактирует информацию о команде. Следующие два сценария проблематичны:

    • Когда пользователь пытается отправить форму, приложение выкинет «Не уникальную» ошибку, это очевидно, потому что таблица «Уникальная» имеет «ключевое имя» для этой команды.
    • Если пользователь изменяет имя команды, приложение должно удалить предыдущее имя команды из таблицы «Уникальные» и должно проверить уникальность «измененного имени команды». Я не могу справиться с этими двумя сценариями.

    Моя функция edit_team выглядит так:

     @app.route('/team/edit/<key>', methods=['GET','POST']) @login_required def edit_team(key): k = db.Key(key) team = db.get(k) form = TeamForm(obj = team, edit=True) # to save old name, doesn't work. if form.validate_on_submit(edit=True): # edit=True is given only in edit function team.name = form.name.data -- others fields are updated in the similar way -- team.put() return redirect(url_for('teams_list')) return render_template('edit_team.html', form=form) 

    Проблема может быть легко решена, если я могу узнать «старое имя» команды, чтобы удалить ее из таблицы «Уникальный». Как вы можете видеть, я сохраняю старое имя команды в функции TeamForm __init __ (), но __init __ () вызывается во время GET (старое имя сохраняется), а также в POST (измененное имя будет сохранено !!). Таким образом, я не могу узнать старое имя вообще, и он остается в таблице «Уникальный», никто не может использовать это «старое имя команды».

    Я попытался объяснить как можно больше, пожалуйста, дайте мне знать, если вы хотите получить дополнительную информацию.

  • Использование меньших операций с хранилищем данных в appengine
  • Создание записи в хранилище данных приводит к зашифрованным свойствам при просмотре в браузере
  • GAE: Как долго ждать возможной согласованности?
  • db.ReferenceProperty () vs ndb.KeyProperty в приложении Engine
  • Загрузка и процесс загрузки файлов в бутылки
  • Google App Engine NDB: как сохранить структуру документа?
  • One Solution collect form web for “Проверка соответствия уникальности при проверке формы в App Engine”

    Изменить: не ответил на ваш вопрос правильно в первый раз.

    Отдельные экземпляры объекта Form будут созданы для запросов GET и POST, поэтому вы не сможете сохранить old_name для себя.

    Вам необходимо передать old_name в браузер в форме и отправить браузеру old_name обратно в запрос POST.

    Легкий способ сделать это – создать скрытое поле формы, которое пользователь не видит, но будет отправлен по запросу POST. Я не слишком хорошо знаком с WTForms, но я предполагаю, что вы можете инициализировать значение поля old_name в обработчике запроса GET.

    Python - лучший язык программирования в мире.