MongoEngine - Custom Query Sets



By default, the objects attribute on a document class returns a QuerySet without applying any filter. However, you can define a classmethod on a document that modifies a queryset. Such a method should accept two arguments – doc_cls and queryset and it needs to be decorated with queryset_manager() in order for it to be recognized.

@queryset_manager
   def qry_method(docs_cls,queryset):
       ….
       ----

In the following example, the document class called products has an expensive_prods() method which is decorated by @queryset_manager. The method itself applies a filter to queryset such that only objects with price >20000 are returned. This method is now the default document query and objects attribute of products class returns filtered documents.

from mongoengine import *
con=connect('newdb')

class products (Document):
   ProductID=IntField(required=True)
   company=StringField()
   Name=StringField()
   price=IntField()

   @queryset_manager
   def expensive_prods(docs_cls,queryset):
      return queryset.filter(price__gt=20000)
for product in products.expensive_prods():
   print ("Name:{} company:{} price:{}".format(product.Name, product.company, product.price))

Output

Name:Laptop company:Acer price:25000
Name:TV company:Samsung price:50000
Name:TV company:Philips price:31000
Name:Laptop company:Dell price:45000

If you wish to customize methods for filtering documents, first declare a subclass of QuerySet class, and use it as value of queryset_class property in meta dictionary.

The example below uses MyQuerySet class as definition of custom queryset. The myqrymethod() in this class filters the documents whose name field ends with ‘er’. In products class, meta attribute refers to this queryset subclass is used as value of queryset_class property.

from mongoengine import *
con=connect('newdb')
class MyQuerySet(QuerySet):
   def myqrymethod(self):
      return self.filter(Name__endswith='er')
class products (Document):
   meta = {'queryset_class': MyQuerySet}
   ProductID=IntField(required=True)
   company=StringField()
   Name=StringField()
   price=IntField()
for product in products.objects.myqrymethod():
   print ("Name:{} company:{} price:{}".format(product.Name, product.company, product.price))

Output

Name:Router company:Iball price:2000
Name:Scanner company:Cannon price:5000
Name:Printer company:Cannon price:12500
Advertisements