Search code examples
pymongoflask-admin

flask-admin and pymongo search


I have the following ModelView

from flask.ext.admin.contrib.pymongo import ModelView
from flask.ext import login
from wtforms import form

class ImageView(ModelView):

    column_labels = dict(
        recordId='Record Id',
        customerId='Customer Id',
        createdAt='Created At',
        updatedAt='Updated At',
        imagePath='Image Path',
        imageUrl='Image Url',
        imageType='Image Type',
        tag='Tag'
    )

    column_list = (
        '_id',
        'recordId',
        'customerId',
        'createdAt',
        'updatedAt',
        'imagePath',
        'imageUrl',
        'imageType',
        'tag'
    )

    column_sortable_list = (
        'customerId',
    )

    column_searchable_list = (
        'customerId',
    )

    form = ImageForm

    def is_accessible(self):
        return login.current_user.is_authenticated()

    def get_list(self, *args, **kwargs):
        count, data = super(ImageView, self).get_list(*args, **kwargs)
        return count, data

And I would like my customer id to be searchable, but unfortunately because it is an integer type in mongodb, the search will not work. How can I implement a custom search function to search that integer? Note that it is completely possible for my customerId to have duplicates because I am not enforcing uniqueness and that's my intent for this mongodb document.


Solution

  • Solved it. All I had to do really was to use custom_filters and apply my custom filter which casts the incoming filter value to an integer.

    Like this:

    class CustomFilterEqual(filters.BasePyMongoFilter):
        """
        Custom filter which casts the filter value as an integer, if possible.
        Failing which it will just set the value to an empty string, returning no results.
        """
        def apply(self, query, value):
            try:
                value = int(value)
            except:
                value = ""
            query.append({self.column: value})
            print(query)
            return query
    
        def operation(self):
            from flask.ext.admin.babel import gettext
            return gettext('equals')
    

    And in my ImageView class above, delete the column_searchable_list attribute and add in the column_filters attribute:

    column_filters = (
        CustomFilterEqual('customerId', 'Customer Id'),
    )