如何解决如何定义接受来自自定义查询工厂的输入的自定义 WTForms 验证器类?
我正在尝试定义一个自定义 WTForms 验证器,我可以使用它来根据在同一表单的多个字段中输入的数据组合检查数据库中是否已存在记录。
我被卡住了,不知道该怎么做。我也是编程新手,仍在尝试了解 Python,老实说,here 和 here 中的一些东西超出了我目前的理解范围。
所以,模型在这里定义:
class Data1(Base):
__tablename__ = 'data1'
id = Column(Integer,primary_key=True,unique=True,nullable=False)
description = Column(String,nullable=False)
class Data2(Base):
__tablename__ = 'data2'
id = Column(Integer,nullable=False)
description = Column(String,nullable=False)
class Data3(Base):
__tablename__ = 'data3'
id = Column(Integer,nullable=False)
data1_id = Column(Integer,ForeignKey('data1.id'),nullable=False)
data2_id = Column(Integer,ForeignKey('data2.id'),nullable=False)
此处的示例数据:
session.add_all([
Data1(id=1,description='a'),Data1(id=2,description='b'),Data1(id=3,description='c'),Data2(id=1,description='aa'),Data2(id=2,description='bb'),Data2(id=3,description='cc'),Data3(id=4,data1_id=1,data2_id=1,description='all first entries of data 1 & 2')
])
session.commit()
问题在我下面的评论中定义:
# Define validator class. This needs to be defined outside the form deFinition since it will be used in a lot of forms.
class Uniqueness(object):
def __init__(self,message=None,dbqry=None):
if not message:
message = u'Duplicate field combination detected!'
self.message = message
self.dbqry = dbqry
def __call__(self):
if self.dbqry:
raise ValidationError(self.message)
# Instantiate validator
uniqueness = Uniqueness
# Define query factory. This needs to be defined outside the form deFinition since it will be used in a lot of forms.
def qry(dbModel,frm,*atts):
# Sample target filter to pass on the query at the bottom of this function:
# fl = [
# Data3.data1_id == Myform.data1_id.data
# Data3.data2_id == Myform.data2_id.data
# Data3.description == Myform.description.data
# ]
# Question1: Referring to the custom validator example [here][3] where 'self' and '.data'
# attributes were used when validator was defined within form class deFinition,# Is my adaptation sample above suited to the purpose,I am trying to achieve here?
# If not,then how should I go about this?
# Question2: How can I generate same list as above which I can pass on to the filter part
# of the query statement at the bottom of this function?
# Below is my attempt to answer this:
fl = []
for att in atts:
try:
hasattr(dbModel,'att')
except AttributeError:
raise AttributeError(f'{dbModel}.{att} is invalid.')
else:
mdl_att = str(getattr(dbModel,att))
# Question3: This is probably wrong since I would then have to use 'eval' at some point right?
# I don't want to use 'eval' if possible.
try:
hasattr(frm,'att')
except AttributeError:
raise AttributeError(f'{frm}.{att} is invalid.')
else:
frm_att = str(getattr(frm,att))
# Question4: If the '.data' attribute from the intended output of the 'fl' example above is indeed required,# How would I state it here?
# Below is suppose to create the list defined above,but I reckon this will create a string
# which I can't use.
# Question6: What is the better way of doing this?
fl.append(mdl_att + '==' + frm_att)
# Query the dbModel to check if a record exists with the data combination as defined in fl filter.
return session.query(dbModel).filter(fl).first()
# Instantiate the query here?
# Question5: 'MyForm' is used before the form class deFinition,How can this be addressed?
dbQry = qry(Data3,MyForm,'data1_id','data2_id','description')
# Define the form
class MyForm(FlaskForm):
# Question5: Or perhaps instantiate inside the form deFinition?
# dbQry = qry(Data3,'description')
# if it should be here then how to properly do it?
choices1 = session.query(Data1.id,Data1.description).all()
data1_id = SelectField('Select Field 1',choices=choices1,validators=[uniqueness(dbqry=dbQry)])
choices2 = session.query(Data2.id,Data2.description).all()
data2_id = SelectField('Select Field 2',choices=choices2,validators=[uniqueness(dbqry=dbQry)])
description = StringField('Description',validators=[Inputrequired(),uniqueness(dbqry=dbQry)])
submit = SubmitField('Submit Data')
# Question5: Or here? 'dbQry' will be used in the above deFinition before the variable deFinition below; How can
# this be addressed?
# dbQry = qry(Data3,'description')
我在自定义验证器的代码中提到的链接是 here。这可能没有正确呈现。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。