I have mapped fields defined in an Interface to a mysql backend database through the use of saconfig and a declarative base.* On my Plone Site instance, I have a form (z3c.form) that will use these fields and will be used to search for "Assets" from a mysql database based on criteria entered in several fields. In my case, I would like to only query on fields that have data entered in them.
This is what my interface and ORMBase class look like:
class IAsset(Interface):
"""Interface class of an asset
"""
Asset_ID = schema.Int(title=u"Asset ID",
required=False
)
GPCL_Asset_ID = schema.TextLine(title=u"GPCL Asset Tracker",
required=False
)
Asset_Type = schema.Int(title=u"Asset Type",
required=False
)
Manufacturer = schema.Int(title=u"Manufacturer",
required=True
)
Model = schema.TextLine(title=u"Serial Number",
required=False
)
Serial_Number = schema.TextLine(title=u"Serial Number",
required=False
)
class Asset(ORMBase):
"""Class for asset
"""
__tablename__ = 'Assets'
Asset_ID = sqlalchemy.Column(sqlalchemy.Integer(),
primary_key=True,
autoincrement=True
)
GPCL_Asset_ID = sqlalchemy.Column(sqlalchemy.String(255),
nullable=True
)
Asset_Type = sqlalchemy.Column(sqlalchemy.Integer(),
nullable=False
)
Manufacturer = sqlalchemy.Column(sqlalchemy.Integer(),
nullable=False
)
Model = sqlalchemy.Column(sqlalchemy.String(255),
nullable=True
)
Serial_Number = sqlalchemy.Column(sqlalchemy.String(255),
nullable=True
)
For testing purposes, I am using the view class of an Asset, and I have a function (current called through a template for testing purposes) that builds a dictionary based on fields that are filled out. I also have a utility class called AssetUtils and there is a function in the class called queryAssets that accepts a dictionary containing the criteria, and returns the search results found.
class View(grok.View):
"""View class
"""
...grok definitions and fields being set for form
def searchAssets(self):
#get data
....
criteria = {}
#build dictionary
#if field (i.e. GPCL_Asset_ID) is not empty, add to the dictionary GPCL_Asset_ID:valueEnteredByUser
assets = queryAssets(criteria)
class AssetUtils(grok.GlobalUtility):
def queryAssets(searchCriteria):
I have a session object defined at the root of the class. In queryAssets I would like to use session.query(Asset).filter() to query the Assets table. The problem I am having though is figuring out what to pass into filter(). I know how to use the query function, like session.query(Asset).filter(GPCL_Asset_ID.like('D%'),Manufacturer==15). However, say Serial Number was present, but GPCL_Asset_ID was not, so I would like to use .filter(Serial_Number.like("EX12%")), and then another case where only Model and Manufacturer were present. .filter(Model.like("A3%"),Manufacturer==32)
So my question is, how can I make it so that .filter filters on fields that were defined/chosen in the dictionary passed into the queryAssets function I have, as opposed to fields being pre-defined in the .filter function?
*I am following along with the book "Professional Plone 4 Development" by Martin Aspeli, chapter 12 and a slideshow presentation ( http://www.slideshare.net/jbellis/pycon-2010-sqlalchemy-tutorial ) - Slide 27, 29. Compared to the slideshow, I am actually using saconfig as found in Martin Aspeli's book.
Looking at your class, from the searchAssets
method you simply need to access the self.request.form
dict-like object and read all the data submitted (by HTTP GET or POST) to that view.
You can then build your list of filters parameters like:
params = []
if 'param1' in self.request.form:
params.append(Asset_ID.like(...))
if ...
session.query(*params)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.