python - Checking uniqueness contraint during form validation in App Engine -
i using flask , wtforms in app engine, trying implement uniqueness contraint on 1 of field. question big, please patient , have been stuck here many hours, need people. started learning app engine, flask , wtforms month ago. in advance.
application has model 'team' shown below:
class team(db.model): name = db.stringproperty(required=true) -- other fields here --
requirement: name of team has unique.
i have followed links
- 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
have come following code:
models.py: created separate table 'unique' given in link:
class unique(db.model): """ handles uniqueness constriant on 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: have overridden __init__() , validate_on_submit() function in uniqueness checked , if not unique, error attached field , validation error raised in same way wtforms's validators.
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 , 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' 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' not unique" % self.name.data) return false return true **---- form fields declaration ----**
the above code works when new team inserted.i mean checks uniqueness properly. problem occurs, when user edits team information. following 2 scenarios problematic:
- when user tries submit form, application throw "not unique" error, obvious because "unique" table has "key_name" team.
- if user changes "team name", application has delete previous team name "unique" table , has check uniqueness "changed team name". not able handle these 2 scenarios.
my edit_team function looks this:
@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) # save old name, doesn't work. if form.validate_on_submit(edit=true): # edit=true given in edit function team.name = form.name.data -- others fields updated in similar way -- team.put() return redirect(url_for('teams_list')) return render_template('edit_team.html', form=form)
problem can solved if able find out 'old name' of team, can delete "unique" table. can see saving old name of team in teamform __init__() function, __init__() called during get(old name saved) , in post(modified name saved!!). so, cannot find out old name @ , remains in "unique" table, nobody can use "old team name" anymore.
i tried explain as possible, please let me know if want more info.
edit: didn't answer question first time.
separate instances of form object instantiated , post requests, can't save old_name self.
you'll need pass old_name browser in form, , have browser submit old_name in post request.
the easyish way create hidden form field user doesn't see, submitted post request. i'm not familiar wtforms assume can initialize old_name field value in request handler.
Comments
Post a Comment