我想禁止用户将重复的网址提交到数据库中。
现在我的方法是:
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()
有什么想法吗?
谢谢!
答案 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)
。