Vic Nicethemer
Vic Nicethemer

Reputation: 1111

Pymongo query normally, but Mongoengine query nothing

Very strange: Pymongo query normally, but Mongoengine query nothing:

class VkWallPostListView(ListView):
    model = VkWallPost
    context_object_name = "vk_list"

    def get_template_names(self):
        return ["blog/vk_list.html"]

    def get_queryset(self):
        wallposts = VkWallPost.objects
        if 'all_posts' not in self.request.GET:
            #wallposts = wallposts.filter(text='S')
            wallposts = VkWallPost._get_collection().find({"text":'S'})
        tag = self.request.GET.get('tag', None)
        if tag:
            wallposts = wallposts.filter(tags=tag)

        return wallposts 

Option wallposts = VkWallPost._get_collection().find({"text":'S'}) return objects, but the same Mongoengine wallposts = wallposts.filter(text='S') is not working - empty results, no errors! The more: i have the same class that query to another collection - there Mongoengine works normally.

Upvotes: 3

Views: 1633

Answers (1)

Adam Lamers
Adam Lamers

Reputation: 1233

It looks like your VkWallPostListView doesn't inherit directly from mongoengine.Document. I recently encountered this as well, where an identical model to the database schema didn't return anything when queried when it inherited from something other than the base Document class. It turns out, mongoengine adds a hidden field to child class documents called _cls and automatically checks for this when querying.

For example:

If I have a class TextHolder that is the base of my class Post

class TextHolder(mongoengine.Document):
    text = mongoengine.StringField()
    meta = { 'allow_inheritance' : True,
             'abstract' : True }

class Post(TextHolder):
    user = mongoengine.ReferenceField(User)

If I tried to query by Posts that already existed in the database, they will not have the _cls field defined in their documents. So, the way to query for documents that do not conform to this standard is to do this.

Post.objects(user=user_to_query_by, class_check=False)

This will give me all objects ignoring the _cls field and not checking for a match with the current model's class name.

Upvotes: 1

Related Questions