web2py:SQLFORM URL重复验证

时间:2014-05-12 04:53:42

标签: web2py

我想禁止用户将重复的网址提交到数据库中。

现在我的方法是:

db.url.URL.requires=[IS_URL(error_message='URL Error'),
                     IS_NOT_IN_DB(db, 'url.URL',error_message='Dupilcated URL')]

它涵盖了“http”而没有“http”的情况。 例如,如果www.123.com已经在数据库中,则用户无法提交http://www.123.com。 但是这种方法不包括“https”的情况,即用户仍然可以提交https://www.123.com

有没有阻止这种重复?

我认为在调用SQLFORM()。process()之前在URL中删除“http”/“https”(如果有的话)。这样,数据库中的URL都没有“http”/“https”。但在调用SQLFORM()。process()。

之前,我不知道如何编辑用户输入

现在我的代码是

url_form=SQLFORM(db.url).process()

有什么想法吗?

谢谢!

2 个答案:

答案 0 :(得分:1)

您可以创建一个custom validator来检查数据库中的http和https版本。这也允许格式化URL。考虑所有小写主机名和删除网址中的关键字参数(?a=b)。如果您打算这样做,请务必查看urlparse

以下代码未经测试,但可能会为您提供足够的代码来创建您自己的解决方案。

class scheme_independant_url_is_not_in_db:
    def __init__(self, db,error_message='Duplicate URL'):
        self.db = db
        self.e = error_message

    def __call__(self, value):
        # test the entered uri
        url_validator = IS_NOT_IN_DB(db,'url.URL')
        value, error = url_validator(value)
        if error: 
            return value,self.e
        # find the opposing scheme
        if value.lower().startswith('http:'):
            opposite_scheme_value =  'https:'+value[5:] 
        elif value.lower().startswith('https:')
            opposite_scheme_value =  'http:'+value[6:] 
        # error on the opposite_scheme_value in db
        value, error = url_validator(opposite_scheme_value)
        if error: 
            return value,self.error_message
        # return the original url, preserving the original scheme
        return (value, None)
... 

db.url.URL.requires=[IS_URL(error_message='URL Error'),
                 scheme_independant_url_is_not_in_db(db)]

答案 1 :(得分:1)

您可以创建自定义验证程序以在进一步处理之前去除http / https:

import re
db.url.URL.requires = [lambda url: (re.sub(r'http[s]?://', '', url), None),
                       IS_URL(error_message='URL Error'),
                       IS_NOT_IN_DB(db, 'url.URL',error_message='Dupilcated URL')]

注意,自定义验证器返回包含更改的URL和None的元组(None表示没有错误)。然后将更改后的URL传递给剩余的两个验证器。

注意,默认情况下,IS_URL会添加" http://"到任何缺少方案的URL(在这种情况下将是所有URL,因为第一个验证器剥离了方案)。要取消该行为,您可以执行IS_URL(prepend_scheme=None)