Sprawdzanie wyjątkowości unikalności podczas walidacji formularza w App Engine

Używam Flask i WTforms w App Engine, próbując zaimplementować unikalność unikalności na jednym z pól. Pytanie jest duże, bądź cierpliwy, a ja utknąłem tu od wielu godzin, potrzebuję pomocy od ciebie. Rozpoczęłam naukę App Engine, Flask i WTForms miesiąc temu. Z góry dziękuję.

Aplikacja ma model „Zespół”, jak pokazano poniżej:

class Team(db.Model):
    name = db.StringProperty(required=True)
    -- some other fields here --

Wymagania: Nazwa zespołu musi być unikalna.

Podążyłem za linkami

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/tutaj-are-only-two-ways-to-enforce-unique-constraints-in-google-app-engine.html

Wymyśliłem następujący kod:

models.py: utworzono oddzielną tabelę „Unique” podaną w linku:

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: Przesłoniłem funkcję __init __ () i validate_on_submit (), w której sprawdzana jest unikalność, a jeśli nie jest unikalna, do tego pola dołączany jest błąd i błąd sprawdzania poprawności zostanie podniesiony w ten sam sposób, co walidatory 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 ----**

Powyższy kod działa, gdy wstawiany jest nowy zespół. Oznacza to, że sprawdza poprawnie unikalność. Problem występuje, gdy użytkownik edytuje informacje o zespole. Następujące dwa scenariusze są problematyczne:

Gdy użytkownik próbuje przesłać formularz, aplikacja zgłasza błąd „Niepowtarzalny”, jest to oczywiste, ponieważ tabela „Unikatowa” ma „nazwę_klucza” dla tego zespołu.Jeśli użytkownik zmieni „nazwę zespołu”, aplikacja musi usunąć poprzednią nazwę zespołu z tabeli „Unikatowy” i musi sprawdzić niepowtarzalność „zmienionej nazwy zespołu”. Nie jestem w stanie poradzić sobie z tymi dwoma scenariuszami.

Moja funkcja edit_team wygląda tak:

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

Problem można łatwo rozwiązać, jeśli jestem w stanie znaleźć „stare imię” zespołu, dzięki czemu mogę go usunąć z tabeli „Unikatowy”. Jak widać, zapisuję starą nazwę zespołu w funkcji TeamForm __init __ (), ale __init __ () jest wywoływana podczas GET (stara nazwa jest zapisywana), a także w POST (zmodyfikowana nazwa zostanie zapisana !!). Więc nie mogę w ogóle znaleźć starej nazwy i pozostaje ona w tabeli „Unikatowy”, nikt nie może już używać tej „starej nazwy drużyny”.

Starałem się wyjaśnić jak najwięcej, daj mi znać, jeśli chcesz uzyskać więcej informacji.

questionAnswers(1)

yourAnswerToTheQuestion