在App Engine的表单验证过程中检查唯一性限制 [英] Checking uniqueness contraint during form validation in App Engine

查看:168
本文介绍了在App Engine的表单验证过程中检查唯一性限制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在App Engine中使用Flask和WTforms,试图在其中一个领域实现唯一性的限制。这个问题很大,请耐心等待,我已经在这里呆了好几个小时,需要你们的帮助。一个月前开始学习App Engine,Flask和WTForms。

应用程序的模型Team如下所示:
$ name $ db






$ pre>

要求:团队的名字必须是唯一的。

我已经按照这个链接进行操作了。




$ b models.py:创建一个单独的表'Unique',如链接所示:

  class唯一(db.Model):

处理字段的唯一性
$ b $ 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:
返回False
uk =唯一(key_name = key_name)
uk.put()
返回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的验证器。

$ p $ class TeamForm(wtf.Form):

def __init __(self,* args,** kwargs):
super(Team (),
如果kwargs.get('edit',None):
self.old_name = self.name.data.lower()

def validate_on_submit(self,edit = False):
如果不是超级(TeamForm,self).validate_on_submit():
返回False
如果编辑:
if self.old_name和self.old_name!= self.name.data.lower():
Unique.delete_entity(self .__ class __.__ name__,self.old_name)
如果不是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:
如果不是,则为:
self.name.errors.append(Value'%s'不是唯一的%self.name.data)
返回False

返回True

** ----表单字段声明---- **

上面的代码在插入新团队时起作用。我的意思是适当地检查唯一性。用户编辑团队信息时会出现问题。以下两种情况是有问题的:


  • 当用户试图提交表单时,应用程序会抛出不唯一的错误, 唯一表具有该组的key_name。

  • 如果用户更改了团队名称,应用程序必须从唯一表中删除以前的团队名称,并且必须检查更改的团队名称的唯一性。我无法处理这两种情况。


    我的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 =真)#保存旧名称,不起作用。
    if form.validate_on_submit(edit = True):#edit = True仅在编辑函数中给出
    team.name = form.name.data
    - 其他字段在类似
    返回重定向(url_for('teams_list'))
    返回render_template('edit_team.html',form = form)

    如果我能够找出团队的旧名称,就可以很容易地解决问题,这样我就可以从独特表。正如你所看到的,我在TeamForm __init __()函数中保存了团队的旧名称,但是在GET(旧名称被保存)和POST(被修改的名称将被保存!!)期间调用__init __()。所以,我根本找不到旧的名字,它仍然在唯一的表格中,没有人可以使用这个旧名称了。



    我试着解释尽可能多的请告诉我,如果你想要更多的信息。

    解决方案

    编辑:没有正确回答你的问题第一次。

    单独的Form对象实例将被实例化为GET和POST请求,所以你不能将old_name保存为self。



    您需要将old_name传递给表单中的浏览器,然后让浏览器将POST返回到POST请求中。



    简单的做法是创建一个隐藏的表单字段,用户不会看到,但会被POST请求提交。我不太熟悉WTForms,但我假设你可以初始化GET请求处理程序中的old_name字段值。

    I am using Flask and WTforms in App Engine, trying to implement uniqueness contraint on one of the field. The question is big, please be patient and I have been stuck here from many hours, need some help from you people. Started learning App Engine, Flask and WTForms a month ago. Thanks in advance.

    Application has model 'Team' as shown below:

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

    Requirement: Name of the team has to be unique.

    I have followed the links

    Have come up with the following code:

    models.py: Created a separate table 'Unique' as given in the link:

    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: I have overridden the __init__() and validate_on_submit() function in which uniqueness is checked and if it is not unique, error is attached to that field and validation error will be raised in the same way as 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 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 ----**
    

    The above code works when new team is inserted.I mean it checks uniqueness properly. The problem occurs, when user edits the team information. Following two scenarios are problematic:

    • When the user tries to submit the form, application will throw "Not unique" error, it is obvious because "Unique" table has "key_name" for this team.
    • If user changes "team name", application has to delete the previous team name from the "Unique" table and has to check uniqueness for the "changed team name". I am not able to handle these two scenarios.

    My edit_team function looks like 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) # 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 can be easily solved if I am able to find out 'old name' of the team, so that I can delete it from the "Unique" table. As you can see I am saving old name of the team in TeamForm __init__() function, but __init__() is called during GET(old name is saved) and also in POST(modified name will get saved!!). So, I cannot find out old name at all and it remains in the "Unique" table, nobody can use this "old team name" anymore.

    I tried to explain as much as possible, please let me know if you want more info.

    解决方案

    Edit: didn't answer your question properly the first time.

    Separate instances of the Form object will be instantiated for the GET and POST requests, so you can't save the old_name to self.

    You'll need to pass the old_name to the browser in the form, and have the browser submit the old_name back in the POST request.

    The easyish way to do this is to create a hidden form field that the user doesn't see, but will get submitted by the POST request. I'm not too familiar with WTForms but I assume you can initialize the old_name field value in your the GET request handler.

    这篇关于在App Engine的表单验证过程中检查唯一性限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆